diff options
Diffstat (limited to 'intern')
199 files changed, 3258 insertions, 4741 deletions
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index 6387fd016ba..e1dfc7043e9 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -11,7 +11,6 @@ add_subdirectory(memutil) add_subdirectory(opencolorio) add_subdirectory(opensubdiv) add_subdirectory(mikktspace) -add_subdirectory(glew-mx) add_subdirectory(eigen) add_subdirectory(sky) diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt index 6aea962eab5..0988b1c0ac4 100644 --- a/intern/cycles/app/CMakeLists.txt +++ b/intern/cycles/app/CMakeLists.txt @@ -43,9 +43,8 @@ else() endif() if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI) - add_definitions(${GL_DEFINITIONS}) - list(APPEND INC_SYS ${GLEW_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS}) - list(APPEND LIB ${CYCLES_GL_LIBRARIES} ${CYCLES_GLEW_LIBRARIES} ${SDL2_LIBRARIES}) + list(APPEND INC_SYS ${Epoxy_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS}) + list(APPEND LIB ${Epoxy_LIBRARIES} ${SDL2_LIBRARIES}) endif() cycles_external_libraries_append(LIB) diff --git a/intern/cycles/app/opengl/display_driver.cpp b/intern/cycles/app/opengl/display_driver.cpp index 8b99f3b6feb..d9c72c07ae4 100644 --- a/intern/cycles/app/opengl/display_driver.cpp +++ b/intern/cycles/app/opengl/display_driver.cpp @@ -7,8 +7,8 @@ #include "util/log.h" #include "util/string.h" -#include <GL/glew.h> #include <SDL.h> +#include <epoxy/gl.h> CCL_NAMESPACE_BEGIN diff --git a/intern/cycles/app/opengl/shader.cpp b/intern/cycles/app/opengl/shader.cpp index 9db9ea7fce9..4d22fc2b763 100644 --- a/intern/cycles/app/opengl/shader.cpp +++ b/intern/cycles/app/opengl/shader.cpp @@ -6,7 +6,7 @@ #include "util/log.h" #include "util/string.h" -#include <GL/glew.h> +#include <epoxy/gl.h> CCL_NAMESPACE_BEGIN diff --git a/intern/cycles/app/opengl/window.cpp b/intern/cycles/app/opengl/window.cpp index 7351ae3eecd..f3352decd08 100644 --- a/intern/cycles/app/opengl/window.cpp +++ b/intern/cycles/app/opengl/window.cpp @@ -11,8 +11,8 @@ #include "util/time.h" #include "util/version.h" -#include <GL/glew.h> #include <SDL.h> +#include <epoxy/gl.h> CCL_NAMESPACE_BEGIN @@ -294,7 +294,6 @@ void window_main_loop(const char *title, SDL_RaiseWindow(V.window); V.gl_context = SDL_GL_CreateContext(V.window); - glewInit(); SDL_GL_MakeCurrent(V.window, nullptr); window_reshape(width, height); diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index a64bcc43191..72f8a4cc15d 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -3,7 +3,6 @@ set(INC .. - ../../glew-mx ../../guardedalloc ../../mikktspace ../../../source/blender/makesdna @@ -14,8 +13,8 @@ set(INC ) set(INC_SYS + ${Epoxy_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS} - ${GLEW_INCLUDE_DIR} ) set(SRC @@ -65,6 +64,7 @@ set(LIB cycles_subd cycles_util + ${Epoxy_LIBRARIES} ${PYTHON_LINKFLAGS} ${PYTHON_LIBRARIES} ) @@ -88,8 +88,6 @@ set(ADDON_FILES addon/version_update.py ) -add_definitions(${GL_DEFINITIONS}) - if(WITH_CYCLES_DEVICE_HIP) add_definitions(-DWITH_HIP) endif() diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 2c926893f9d..859560c8062 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -83,6 +83,7 @@ enum_use_layer_samples = ( enum_sampling_pattern = ( ('SOBOL', "Sobol", "Use Sobol random sampling pattern", 0), ('PROGRESSIVE_MULTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern", 1), + ('SOBOL_BURLEY', "Sobol-Burley", "Use Sobol-Burley random sampling pattern", 2), ) enum_volume_sampling = ( diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp index ca1aa6329d9..109408c354d 100644 --- a/intern/cycles/blender/object.cpp +++ b/intern/cycles/blender/object.cpp @@ -66,12 +66,6 @@ bool BlenderSync::object_is_geometry(BObjectInfo &b_ob_info) return true; } - /* Other object types that are not meshes but evaluate to meshes are presented to render engines - * as separate instance objects. Metaballs have not been affected by that change yet. */ - if (type == BL::Object::type_META) { - return true; - } - return b_ob_data.is_a(&RNA_Mesh); } diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp index 8b2b331f73e..1e33b0b7207 100644 --- a/intern/cycles/blender/python.cpp +++ b/intern/cycles/blender/python.cpp @@ -59,8 +59,6 @@ static void debug_flags_sync_from_scene(BL::Scene b_scene) { DebugFlagsRef flags = DebugFlags(); PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - /* Synchronize shared flags. */ - flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type"); /* Synchronize CPU flags. */ flags.cpu.avx2 = get_boolean(cscene, "debug_use_cpu_avx2"); flags.cpu.avx = get_boolean(cscene, "debug_use_cpu_avx"); @@ -140,8 +138,6 @@ static PyObject *init_func(PyObject * /*self*/, PyObject *args) BlenderSession::headless = headless; - DebugFlags().running_inside_blender = true; - Py_RETURN_NONE; } diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp index 6d27b8e7d87..e1da85b84ff 100644 --- a/intern/cycles/blender/session.cpp +++ b/intern/cycles/blender/session.cpp @@ -110,7 +110,8 @@ void BlenderSession::create_session() { const SessionParams session_params = BlenderSync::get_session_params( b_engine, b_userpref, b_scene, background); - const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); + const SceneParams scene_params = BlenderSync::get_scene_params( + b_scene, background, use_developer_ui); const bool session_pause = BlenderSync::get_session_pause(b_scene, background); /* reset status/progress */ @@ -196,7 +197,8 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg const SessionParams session_params = BlenderSync::get_session_params( b_engine, b_userpref, b_scene, background); - const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); + const SceneParams scene_params = BlenderSync::get_scene_params( + b_scene, background, use_developer_ui); if (scene->params.modified(scene_params) || session->params.modified(session_params) || !this->b_render.use_persistent_data()) { @@ -724,7 +726,8 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_) /* on session/scene parameter changes, we recreate session entirely */ const SessionParams session_params = BlenderSync::get_session_params( b_engine, b_userpref, b_scene, background); - const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background); + const SceneParams scene_params = BlenderSync::get_scene_params( + b_scene, background, use_developer_ui); const bool session_pause = BlenderSync::get_session_pause(b_scene, background); if (session->params.modified(session_params) || scene->params.modified(scene_params)) { diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index 429a8e665af..0d4c1d70180 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -801,7 +801,9 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph) /* Scene Parameters */ -SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background) +SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, + const bool background, + const bool use_developer_ui) { SceneParams params; PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); @@ -812,7 +814,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background) else if (shadingsystem == 1) params.shadingsystem = SHADINGSYSTEM_OSL; - if (background || DebugFlags().viewport_static_bvh) + if (background || (use_developer_ui && get_enum(cscene, "debug_bvh_type"))) params.bvh_type = BVH_TYPE_STATIC; else params.bvh_type = BVH_TYPE_DYNAMIC; diff --git a/intern/cycles/blender/sync.h b/intern/cycles/blender/sync.h index 0ad4ca6fe83..ae6c2420e55 100644 --- a/intern/cycles/blender/sync.h +++ b/intern/cycles/blender/sync.h @@ -84,7 +84,9 @@ class BlenderSync { } /* get parameters */ - static SceneParams get_scene_params(BL::Scene &b_scene, bool background); + static SceneParams get_scene_params(BL::Scene &b_scene, + const bool background, + const bool use_developer_ui); static SessionParams get_session_params(BL::RenderEngine &b_engine, BL::Preferences &b_userpref, BL::Scene &b_scene, diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake index 00a824ca99a..aaeb85f700d 100644 --- a/intern/cycles/cmake/external_libs.cmake +++ b/intern/cycles/cmake/external_libs.cmake @@ -505,26 +505,19 @@ if(CYCLES_STANDALONE_REPOSITORY) endif() ########################################################################### -# GLEW +# Epoxy ########################################################################### if(CYCLES_STANDALONE_REPOSITORY) if((WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI) OR WITH_CYCLES_HYDRA_RENDER_DELEGATE) if(MSVC AND EXISTS ${_cycles_lib_dir}) - set(GLEW_LIBRARY "${_cycles_lib_dir}/opengl/lib/glew.lib") - set(GLEW_INCLUDE_DIR "${_cycles_lib_dir}/opengl/include") - add_definitions(-DGLEW_STATIC) + set(Epoxy_LIBRARIES "${_cycles_lib_dir}/epoxy/lib/epoxy.lib") + set(Epoxy_INCLUDE_DIRS "${_cycles_lib_dir}/epoxy/include") else() - find_package(GLEW REQUIRED) + find_package(Epoxy REQUIRED) endif() - - set(CYCLES_GLEW_LIBRARIES ${GLEW_LIBRARY}) endif() -else() - # Workaround for unconventional variable name use in Blender. - set(GLEW_INCLUDE_DIR "${GLEW_INCLUDE_PATH}") - set(CYCLES_GLEW_LIBRARIES bf_intern_glew_mx ${BLENDER_GLEW_LIBRARIES}) endif() ########################################################################### @@ -557,25 +550,6 @@ if(EXISTS ${_cycles_lib_dir}) endif() ########################################################################### -# OpenGL -########################################################################### - -if((WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI) OR - WITH_CYCLES_HYDRA_RENDER_DELEGATE) - if(CYCLES_STANDALONE_REPOSITORY) - if(NOT DEFINED OpenGL_GL_PREFERENCE) - set(OpenGL_GL_PREFERENCE "LEGACY") - endif() - - find_package(OpenGL REQUIRED) - - set(CYCLES_GL_LIBRARIES ${OPENGL_gl_LIBRARY}) - else() - set(CYCLES_GL_LIBRARIES ${BLENDER_GL_LIBRARIES}) - endif() -endif() - -########################################################################### # SDL ########################################################################### diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index 6418801c572..4ae123cd634 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -3,12 +3,9 @@ set(INC .. - ../../glew-mx ) -set(INC_SYS - ${GLEW_INCLUDE_DIR} -) +set(INC_SYS ) if(WITH_CYCLES_DEVICE_OPTIX OR WITH_CYCLES_DEVICE_CUDA) if(WITH_CUDA_DYNLOAD) @@ -150,7 +147,6 @@ set(SRC set(LIB cycles_kernel cycles_util - ${CYCLES_GL_LIBRARIES} ) if(WITH_CYCLES_DEVICE_OPTIX OR WITH_CYCLES_DEVICE_CUDA) @@ -171,8 +167,6 @@ if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD) ) endif() -add_definitions(${GL_DEFINITIONS}) - if(WITH_CYCLES_DEVICE_CUDA) add_definitions(-DWITH_CUDA) endif() diff --git a/intern/cycles/device/hip/device_impl.cpp b/intern/cycles/device/hip/device_impl.cpp index 82db55ea715..a84f1edd70e 100644 --- a/intern/cycles/device/hip/device_impl.cpp +++ b/intern/cycles/device/hip/device_impl.cpp @@ -16,7 +16,6 @@ # include "util/log.h" # include "util/map.h" # include "util/md5.h" -# include "util/opengl.h" # include "util/path.h" # include "util/string.h" # include "util/system.h" diff --git a/intern/cycles/hydra/CMakeLists.txt b/intern/cycles/hydra/CMakeLists.txt index aa194fb936e..2bbd46db582 100644 --- a/intern/cycles/hydra/CMakeLists.txt +++ b/intern/cycles/hydra/CMakeLists.txt @@ -10,14 +10,14 @@ set(INC ) set(INC_SYS ${USD_INCLUDE_DIRS} - ${GLEW_INCLUDE_DIR} + ${Epoxy_INCLUDE_DIRS} ) set(LIB cycles_scene cycles_session cycles_graph - ${CYCLES_GLEW_LIBRARIES} + ${Epoxy_LIBRARIES} ) cycles_external_libraries_append(LIB) @@ -64,8 +64,6 @@ set(SRC_HD_CYCLES volume.cpp ) -add_definitions(${GL_DEFINITIONS}) - if(WITH_OPENVDB) add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS}) list(APPEND INC_SYS diff --git a/intern/cycles/hydra/display_driver.cpp b/intern/cycles/hydra/display_driver.cpp index 0c0b577c358..1a989605335 100644 --- a/intern/cycles/hydra/display_driver.cpp +++ b/intern/cycles/hydra/display_driver.cpp @@ -11,7 +11,7 @@ #include "hydra/render_buffer.h" #include "hydra/session.h" -#include <GL/glew.h> +#include <epoxy/gl.h> #include <pxr/imaging/hgiGL/texture.h> HDCYCLES_NAMESPACE_OPEN_SCOPE diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 7c31b21797f..f32a810786d 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -274,6 +274,8 @@ set(SRC_KERNEL_SAMPLE_HEADERS sample/mapping.h sample/mis.h sample/pattern.h + sample/sobol_burley.h + sample/util.h ) set(SRC_KERNEL_UTIL_HEADERS @@ -343,6 +345,7 @@ set(SRC_UTIL_HEADERS ../util/types_int3_impl.h ../util/types_int4.h ../util/types_int4_impl.h + ../util/types_spectrum.h ../util/types_uchar2.h ../util/types_uchar2_impl.h ../util/types_uchar3.h @@ -356,8 +359,6 @@ set(SRC_UTIL_HEADERS ../util/types_uint4.h ../util/types_uint4_impl.h ../util/types_ushort4.h - ../util/types_vector3.h - ../util/types_vector3_impl.h ) set(LIB diff --git a/intern/cycles/kernel/bake/bake.h b/intern/cycles/kernel/bake/bake.h index ec87990b699..9d53d71b431 100644 --- a/intern/cycles/kernel/bake/bake.h +++ b/intern/cycles/kernel/bake/bake.h @@ -8,6 +8,8 @@ #include "kernel/geom/geom.h" +#include "kernel/util/color.h" + CCL_NAMESPACE_BEGIN ccl_device void kernel_displace_evaluate(KernelGlobals kg, @@ -65,7 +67,7 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg, shader_eval_surface<KERNEL_FEATURE_NODE_MASK_SURFACE_LIGHT & ~(KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_NODE_LIGHT_PATH)>( kg, INTEGRATOR_STATE_NULL, &sd, NULL, path_flag); - float3 color = shader_background_eval(&sd); + Spectrum color = shader_background_eval(&sd); #ifdef __KERNEL_DEBUG_NAN__ if (!isfinite_safe(color)) { @@ -76,10 +78,12 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg, /* Ensure finite color, avoiding possible numerical instabilities in the path tracing kernels. */ color = ensure_finite(color); + float3 color_rgb = spectrum_to_rgb(color); + /* Write output. */ - output[offset * 3 + 0] += color.x; - output[offset * 3 + 1] += color.y; - output[offset * 3 + 2] += color.z; + output[offset * 3 + 0] += color_rgb.x; + output[offset * 3 + 1] += color_rgb.y; + output[offset * 3 + 2] += color_rgb.z; } ccl_device void kernel_curve_shadow_transparency_evaluate( diff --git a/intern/cycles/kernel/closure/alloc.h b/intern/cycles/kernel/closure/alloc.h index 933c07a5102..9847898ee89 100644 --- a/intern/cycles/kernel/closure/alloc.h +++ b/intern/cycles/kernel/closure/alloc.h @@ -8,7 +8,7 @@ CCL_NAMESPACE_BEGIN ccl_device ccl_private ShaderClosure *closure_alloc(ccl_private ShaderData *sd, int size, ClosureType type, - float3 weight) + Spectrum weight) { kernel_assert(size <= sizeof(ShaderClosure)); @@ -49,7 +49,7 @@ ccl_device ccl_private void *closure_alloc_extra(ccl_private ShaderData *sd, int ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *sd, int size, - float3 weight) + Spectrum weight) { kernel_assert(isfinite_safe(weight)); @@ -74,7 +74,7 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData * #ifdef __OSL__ ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd, int size, - float3 weight, + Spectrum weight, void *data) { kernel_assert(isfinite_safe(weight)); diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 4feb21c43e3..d6b7e7bfa88 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -103,9 +103,8 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private differential3 *domega_in, ccl_private float *pdf) { /* For curves use the smooth normal, particularly for ribbons the geometric @@ -115,304 +114,80 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, switch (sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - label = bsdf_diffuse_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; #ifdef __SVM__ case CLOSURE_BSDF_OREN_NAYAR_ID: - label = bsdf_oren_nayar_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_oren_nayar_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; # ifdef __OSL__ case CLOSURE_BSDF_PHONG_RAMP_ID: - label = bsdf_phong_ramp_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_phong_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_DIFFUSE_RAMP_ID: - label = bsdf_diffuse_ramp_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_diffuse_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; # endif case CLOSURE_BSDF_TRANSLUCENT_ID: - label = bsdf_translucent_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_translucent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: - label = bsdf_reflection_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: - label = bsdf_refraction_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: - label = bsdf_transparent_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_transparent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - label = bsdf_microfacet_ggx_sample(kg, - sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_microfacet_ggx_sample(kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: - label = bsdf_microfacet_multi_ggx_sample(kg, - sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf, - &sd->lcg_state); + label = bsdf_microfacet_multi_ggx_sample( + kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, &sd->lcg_state); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: - label = bsdf_microfacet_multi_ggx_glass_sample(kg, - sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf, - &sd->lcg_state); + label = bsdf_microfacet_multi_ggx_glass_sample( + kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, &sd->lcg_state); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - label = bsdf_microfacet_beckmann_sample(kg, - sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_microfacet_beckmann_sample( + kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: - label = bsdf_ashikhmin_shirley_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_ashikhmin_shirley_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - label = bsdf_ashikhmin_velvet_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: - label = bsdf_diffuse_toon_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_diffuse_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_GLOSSY_TOON_ID: - label = bsdf_glossy_toon_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_glossy_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: - label = bsdf_hair_reflection_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_hair_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: - label = bsdf_hair_transmission_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_hair_transmission_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: - label = bsdf_principled_hair_sample( - kg, sc, sd, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf); + label = bsdf_principled_hair_sample(kg, sc, sd, randu, randv, eval, omega_in, pdf); break; # ifdef __PRINCIPLED__ case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: - label = bsdf_principled_diffuse_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID: - label = bsdf_principled_sheen_sample(sc, - Ng, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + label = bsdf_principled_sheen_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); break; # endif /* __PRINCIPLED__ */ #endif @@ -458,7 +233,7 @@ ccl_device #else ccl_device_inline #endif - float3 + Spectrum bsdf_eval(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private const ShaderClosure *sc, @@ -466,7 +241,7 @@ ccl_device_inline const bool is_transmission, ccl_private float *pdf) { - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); if (!is_transmission) { switch (sc->type) { diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h index 47066542122..75995262030 100644 --- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h @@ -39,7 +39,7 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough return 2.0f / (roughness * roughness) - 2.0f; } -ccl_device_forceinline float3 +ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc, const float3 I, const float3 omega_in, @@ -55,7 +55,7 @@ bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc, if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } if (NdotI > 0.0f && NdotO > 0.0f) { NdotI = fmaxf(NdotI, 1e-6f); @@ -105,16 +105,16 @@ bsdf_ashikhmin_shirley_eval_reflect(ccl_private const ShaderClosure *sc, } } - return make_float3(out, out, out); + return make_spectrum(out); } -ccl_device float3 bsdf_ashikhmin_shirley_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_ashikhmin_shirley_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, @@ -133,14 +133,10 @@ ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; @@ -214,19 +210,13 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) { /* Some high number for MIS. */ *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); + *eval = make_spectrum(1e6f); label = LABEL_REFLECT | LABEL_SINGULAR; } else { /* leave the rest to eval_reflect */ *eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf); } - -#ifdef __RAY_DIFFERENTIALS__ - /* just do the reflection thing for now */ - *domega_in_dx = (2.0f * dot(N, dIdx)) * N - dIdx; - *domega_in_dy = (2.0f * dot(N, dIdy)) * N - dIdy; -#endif } return label; diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h index 3d7906eef7d..9e68ea5d5e5 100644 --- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h @@ -31,10 +31,10 @@ ccl_device int bsdf_ashikhmin_velvet_setup(ccl_private VelvetBsdf *bsdf) return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc; float m_invsigma2 = bsdf->invsigma2; @@ -50,7 +50,7 @@ ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClo if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } float cosNHdivHO = cosNH / cosHO; cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f); @@ -68,33 +68,29 @@ ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(ccl_private const ShaderClo float out = 0.25f * (D * G) / cosNO; *pdf = 0.5f * M_1_PI_F; - return make_float3(out, out, out); + return make_spectrum(out); } *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_ashikhmin_velvet_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_ashikhmin_velvet_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc; @@ -129,22 +125,16 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc, float power = 0.25f * (D * G) / cosNO; - *eval = make_float3(power, power, power); - -#ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the retroreflective bounce - *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; - *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; -#endif + *eval = make_spectrum(power); } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } return LABEL_REFLECT | LABEL_DIFFUSE; } diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h index 759ad03f8e8..ec64c375666 100644 --- a/intern/cycles/kernel/closure/bsdf_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_diffuse.h @@ -26,39 +26,35 @@ ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf) return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_diffuse_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_diffuse_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc; float3 N = bsdf->N; float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; *pdf = cos_pi; - return make_float3(cos_pi, cos_pi, cos_pi); + return make_spectrum(cos_pi); } -ccl_device float3 bsdf_diffuse_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_diffuse_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc; @@ -68,16 +64,11 @@ ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc, sample_cos_hemisphere(N, randu, randv, omega_in, pdf); if (dot(Ng, *omega_in) > 0.0f) { - *eval = make_float3(*pdf, *pdf, *pdf); -#ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; - *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; -#endif + *eval = make_spectrum(*pdf); } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } return LABEL_REFLECT | LABEL_DIFFUSE; } @@ -90,39 +81,35 @@ ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf) return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_translucent_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_translucent_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_translucent_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_translucent_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc; float3 N = bsdf->N; float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F; *pdf = cos_pi; - return make_float3(cos_pi, cos_pi, cos_pi); + return make_spectrum(cos_pi); } ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc; @@ -132,16 +119,11 @@ ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc, // distribution over the hemisphere sample_cos_hemisphere(-N, randu, randv, omega_in, pdf); if (dot(Ng, *omega_in) < 0) { - *eval = make_float3(*pdf, *pdf, *pdf); -#ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx); - *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy); -#endif + *eval = make_spectrum(*pdf); } else { *pdf = 0; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } return LABEL_TRANSMIT | LABEL_DIFFUSE; } diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h index aa4c091f587..d7faf5c9e9a 100644 --- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h +++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h @@ -9,6 +9,7 @@ #pragma once #include "kernel/sample/mapping.h" +#include "kernel/util/color.h" CCL_NAMESPACE_BEGIN @@ -46,38 +47,34 @@ ccl_device void bsdf_diffuse_ramp_blur(ccl_private ShaderClosure *sc, float roug { } -ccl_device float3 bsdf_diffuse_ramp_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_diffuse_ramp_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc; float3 N = bsdf->N; float cos_pi = fmaxf(dot(N, omega_in), 0.0f); *pdf = cos_pi * M_1_PI_F; - return bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F; + return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F); } -ccl_device float3 bsdf_diffuse_ramp_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_diffuse_ramp_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc; @@ -87,15 +84,11 @@ ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc, sample_cos_hemisphere(N, randu, randv, omega_in, pdf); if (dot(Ng, *omega_in) > 0.0f) { - *eval = bsdf_diffuse_ramp_get_color(bsdf->colors, *pdf * M_PI_F) * M_1_PI_F; -# ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx; - *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy; -# endif + *eval = rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, *pdf * M_PI_F) * M_1_PI_F); } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } return LABEL_REFLECT | LABEL_DIFFUSE; } diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h index a136ed05800..a29f7c444ae 100644 --- a/intern/cycles/kernel/closure/bsdf_hair.h +++ b/intern/cycles/kernel/closure/bsdf_hair.h @@ -37,10 +37,10 @@ ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf) return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc; float offset = bsdf->offset; @@ -61,7 +61,7 @@ ccl_device float3 bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClos if (M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f) { *pdf = 0.0f; - return make_float3(*pdf, *pdf, *pdf); + return zero_spectrum(); } float roughness1_inv = 1.0f / roughness1; @@ -81,31 +81,31 @@ ccl_device float3 bsdf_hair_reflection_eval_reflect(ccl_private const ShaderClos (2 * (t * t + roughness1 * roughness1) * (a_R - b_R) * costheta_i); *pdf = phi_pdf * theta_pdf; - return make_float3(*pdf, *pdf, *pdf); + return make_spectrum(*pdf); } -ccl_device float3 bsdf_hair_transmission_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_hair_transmission_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_hair_reflection_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_hair_reflection_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_hair_transmission_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_hair_transmission_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc; float offset = bsdf->offset; @@ -125,7 +125,7 @@ ccl_device float3 bsdf_hair_transmission_eval_transmit(ccl_private const ShaderC if (M_PI_2_F - fabsf(theta_i) < 0.001f) { *pdf = 0.0f; - return make_float3(*pdf, *pdf, *pdf); + return zero_spectrum(); } float costheta_i = fast_cosf(theta_i); @@ -145,20 +145,16 @@ ccl_device float3 bsdf_hair_transmission_eval_transmit(ccl_private const ShaderC float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2)); *pdf = phi_pdf * theta_pdf; - return make_float3(*pdf, *pdf, *pdf); + return make_spectrum(*pdf); } ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc; @@ -194,17 +190,11 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc, fast_sincosf(phi, &sinphi, &cosphi); *omega_in = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg; - // differentials - TODO: find a better approximation for the reflective bounce -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = 2 * dot(locy, dIdx) * locy - dIdx; - *domega_in_dy = 2 * dot(locy, dIdy) * locy - dIdy; -#endif - *pdf = fabsf(phi_pdf * theta_pdf); if (M_PI_2_F - fabsf(theta_i) < 0.001f) *pdf = 0.0f; - *eval = make_float3(*pdf, *pdf, *pdf); + *eval = make_spectrum(*pdf); return LABEL_REFLECT | LABEL_GLOSSY; } @@ -212,14 +202,10 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc, ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc; @@ -255,18 +241,12 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc fast_sincosf(phi, &sinphi, &cosphi); *omega_in = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg; - // differentials - TODO: find a better approximation for the transmission bounce -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = 2 * dot(locy, dIdx) * locy - dIdx; - *domega_in_dy = 2 * dot(locy, dIdy) * locy - dIdy; -#endif - *pdf = fabsf(phi_pdf * theta_pdf); if (M_PI_2_F - fabsf(theta_i) < 0.001f) { *pdf = 0.0f; } - *eval = make_float3(*pdf, *pdf, *pdf); + *eval = make_spectrum(*pdf); /* TODO(sergey): Should always be negative, but seems some precision issue * is involved here. diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index e7f24b89458..2236bc62050 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -20,7 +20,7 @@ typedef struct PrincipledHairBSDF { SHADER_CLOSURE_BASE; /* Absorption coefficient. */ - float3 sigma; + Spectrum sigma; /* Variance of the underlying logistic distribution. */ float v; /* Scale factor of the underlying logistic distribution. */ @@ -166,12 +166,6 @@ ccl_device_inline float longitudinal_scattering( } } -/* Combine the three values using their luminances. */ -ccl_device_inline float4 combine_with_energy(KernelGlobals kg, float3 c) -{ - return make_float4(c.x, c.y, c.z, linear_rgb_to_gray(kg, c)); -} - #ifdef __HAIR__ /* Set up the hair closure. */ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd, @@ -214,34 +208,36 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd, #endif /* __HAIR__ */ /* Given the Fresnel term and transmittance, generate the attenuation terms for each bounce. */ -ccl_device_inline void hair_attenuation(KernelGlobals kg, - float f, - float3 T, - ccl_private float4 *Ap) +ccl_device_inline void hair_attenuation( + KernelGlobals kg, float f, Spectrum T, ccl_private Spectrum *Ap, ccl_private float *Ap_energy) { /* Primary specular (R). */ - Ap[0] = make_float4(f, f, f, f); + Ap[0] = make_spectrum(f); + Ap_energy[0] = f; /* Transmission (TT). */ - float3 col = sqr(1.0f - f) * T; - Ap[1] = combine_with_energy(kg, col); + Spectrum col = sqr(1.0f - f) * T; + Ap[1] = col; + Ap_energy[1] = spectrum_to_gray(kg, col); /* Secondary specular (TRT). */ col *= T * f; - Ap[2] = combine_with_energy(kg, col); + Ap[2] = col; + Ap_energy[2] = spectrum_to_gray(kg, col); /* Residual component (TRRT+). */ - col *= safe_divide_color(T * f, make_float3(1.0f, 1.0f, 1.0f) - T * f); - Ap[3] = combine_with_energy(kg, col); + col *= safe_divide(T * f, one_spectrum() - T * f); + Ap[3] = col; + Ap_energy[3] = spectrum_to_gray(kg, col); /* Normalize sampling weights. */ - float totweight = Ap[0].w + Ap[1].w + Ap[2].w + Ap[3].w; + float totweight = Ap_energy[0] + Ap_energy[1] + Ap_energy[2] + Ap_energy[3]; float fac = safe_divide(1.0f, totweight); - Ap[0].w *= fac; - Ap[1].w *= fac; - Ap[2].w *= fac; - Ap[3].w *= fac; + Ap_energy[0] *= fac; + Ap_energy[1] *= fac; + Ap_energy[2] *= fac; + Ap_energy[3] *= fac; } /* Given the tilt angle, generate the rotated theta_i for the different bounces. */ @@ -266,11 +262,11 @@ ccl_device_inline void hair_alpha_angles(float sin_theta_i, } /* Evaluation function for our shader. */ -ccl_device float3 bsdf_principled_hair_eval(KernelGlobals kg, - ccl_private const ShaderData *sd, - ccl_private const ShaderClosure *sc, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg, + ccl_private const ShaderData *sd, + ccl_private const ShaderClosure *sc, + const float3 omega_in, + ccl_private float *pdf) { kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length)); @@ -299,9 +295,11 @@ ccl_device float3 bsdf_principled_hair_eval(KernelGlobals kg, float cos_gamma_t = cos_from_sin(sin_gamma_t); float gamma_t = safe_asinf(sin_gamma_t); - float3 T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t)); - float4 Ap[4]; - hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap); + Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t)); + Spectrum Ap[4]; + float Ap_energy[4]; + hair_attenuation( + kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy); float sin_theta_i = wi.x; float cos_theta_i = cos_from_sin(sin_theta_i); @@ -312,35 +310,40 @@ ccl_device float3 bsdf_principled_hair_eval(KernelGlobals kg, float angles[6]; hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles); - float4 F; + Spectrum F; + float F_energy; float Mp, Np; /* Primary specular (R). */ Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness); Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t); F = Ap[0] * Mp * Np; - kernel_assert(isfinite_safe(float4_to_float3(F))); + F_energy = Ap_energy[0] * Mp * Np; + kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy)); /* Transmission (TT). */ Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v); Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t); F += Ap[1] * Mp * Np; - kernel_assert(isfinite_safe(float4_to_float3(F))); + F_energy += Ap_energy[1] * Mp * Np; + kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy)); /* Secondary specular (TRT). */ Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v); Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t); F += Ap[2] * Mp * Np; - kernel_assert(isfinite_safe(float4_to_float3(F))); + F_energy += Ap_energy[2] * Mp * Np; + kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy)); /* Residual component (TRRT+). */ Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v); Np = M_1_2PI_F; F += Ap[3] * Mp * Np; - kernel_assert(isfinite_safe(float4_to_float3(F))); + F_energy += Ap_energy[3] * Mp * Np; + kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy)); - *pdf = F.w; - return float4_to_float3(F); + *pdf = F_energy; + return F; } /* Sampling function for the hair shader. */ @@ -349,10 +352,8 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, ccl_private ShaderData *sd, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc; @@ -385,16 +386,18 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, float cos_gamma_t = cos_from_sin(sin_gamma_t); float gamma_t = safe_asinf(sin_gamma_t); - float3 T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t)); - float4 Ap[4]; - hair_attenuation(kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap); + Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t)); + Spectrum Ap[4]; + float Ap_energy[4]; + hair_attenuation( + kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy); int p = 0; for (; p < 3; p++) { - if (u[0].x < Ap[p].w) { + if (u[0].x < Ap_energy[p]) { break; } - u[0].x -= Ap[p].w; + u[0].x -= Ap_energy[p]; } float v = bsdf->v; @@ -429,44 +432,43 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles); - float4 F; + Spectrum F; + float F_energy; float Mp, Np; /* Primary specular (R). */ Mp = longitudinal_scattering(angles[0], angles[1], sin_theta_o, cos_theta_o, bsdf->m0_roughness); Np = azimuthal_scattering(phi, 0, bsdf->s, gamma_o, gamma_t); F = Ap[0] * Mp * Np; - kernel_assert(isfinite_safe(float4_to_float3(F))); + F_energy = Ap_energy[0] * Mp * Np; + kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy)); /* Transmission (TT). */ Mp = longitudinal_scattering(angles[2], angles[3], sin_theta_o, cos_theta_o, 0.25f * bsdf->v); Np = azimuthal_scattering(phi, 1, bsdf->s, gamma_o, gamma_t); F += Ap[1] * Mp * Np; - kernel_assert(isfinite_safe(float4_to_float3(F))); + F_energy += Ap_energy[1] * Mp * Np; + kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy)); /* Secondary specular (TRT). */ Mp = longitudinal_scattering(angles[4], angles[5], sin_theta_o, cos_theta_o, 4.0f * bsdf->v); Np = azimuthal_scattering(phi, 2, bsdf->s, gamma_o, gamma_t); F += Ap[2] * Mp * Np; - kernel_assert(isfinite_safe(float4_to_float3(F))); + F_energy += Ap_energy[2] * Mp * Np; + kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy)); /* Residual component (TRRT+). */ Mp = longitudinal_scattering(sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v); Np = M_1_2PI_F; F += Ap[3] * Mp * Np; - kernel_assert(isfinite_safe(float4_to_float3(F))); + F_energy += Ap_energy[3] * Mp * Np; + kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy)); - *eval = float4_to_float3(F); - *pdf = F.w; + *eval = F; + *pdf = F_energy; *omega_in = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i); -#ifdef __RAY_DIFFERENTIALS__ - float3 N = safe_normalize(sd->I + *omega_in); - *domega_in_dx = (2 * dot(N, sd->dI.dx)) * N - sd->dI.dx; - *domega_in_dy = (2 * dot(N, sd->dI.dy)) * N - sd->dI.dy; -#endif - return LABEL_GLOSSY | ((p == 0) ? LABEL_REFLECT : LABEL_TRANSMIT); } @@ -489,25 +491,28 @@ ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale( return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f; } -ccl_device float3 bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc) +ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc) { ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc; return exp(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v)); } -ccl_device_inline float3 -bsdf_principled_hair_sigma_from_reflectance(const float3 color, const float azimuthal_roughness) +ccl_device_inline Spectrum +bsdf_principled_hair_sigma_from_reflectance(const Spectrum color, const float azimuthal_roughness) { - const float3 sigma = log(color) / - bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness); + const Spectrum sigma = log(color) / + bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness); return sigma * sigma; } -ccl_device_inline float3 bsdf_principled_hair_sigma_from_concentration(const float eumelanin, - const float pheomelanin) +ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_concentration(const float eumelanin, + const float pheomelanin) { - return eumelanin * make_float3(0.506f, 0.841f, 1.653f) + - pheomelanin * make_float3(0.343f, 0.733f, 1.924f); + const float3 eumelanin_color = make_float3(0.506f, 0.841f, 1.653f); + const float3 pheomelanin_color = make_float3(0.343f, 0.733f, 1.924f); + + return eumelanin * rgb_to_spectrum(eumelanin_color) + + pheomelanin * rgb_to_spectrum(pheomelanin_color); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index c6cbd1ffae7..04d5ca90bfd 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -17,8 +17,8 @@ CCL_NAMESPACE_BEGIN typedef struct MicrofacetExtra { - float3 color, cspec0; - float3 fresnel_color; + Spectrum color, cspec0; + Spectrum fresnel_color; float clearcoat; } MicrofacetExtra; @@ -233,11 +233,11 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, * * Else it is simply white */ -ccl_device_forceinline float3 reflection_color(ccl_private const MicrofacetBsdf *bsdf, - float3 L, - float3 H) +ccl_device_forceinline Spectrum reflection_color(ccl_private const MicrofacetBsdf *bsdf, + float3 L, + float3 H) { - float3 F = make_float3(1.0f, 1.0f, 1.0f); + Spectrum F = one_spectrum(); bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID); if (use_fresnel) { @@ -357,10 +357,10 @@ ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float ro bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y); } -ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; float alpha_x = bsdf->alpha_x; @@ -370,7 +370,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosu if (m_refractive || alpha_x * alpha_y <= 1e-7f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } float cosNO = dot(N, I); @@ -451,12 +451,12 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosu /* eq. 20 */ float common = D * 0.25f / cosNO; - float3 F = reflection_color(bsdf, omega_in, m); + Spectrum F = reflection_color(bsdf, omega_in, m); if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { F *= 0.25f * bsdf->extra->clearcoat; } - float3 out = F * G * common; + Spectrum out = F * G * common; /* eq. 2 in distribution of visible normals sampling * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */ @@ -469,13 +469,13 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(ccl_private const ShaderClosu return out; } - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; float alpha_x = bsdf->alpha_x; @@ -486,7 +486,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClos if (!m_refractive || alpha_x * alpha_y <= 1e-7f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } float cosNO = dot(N, I); @@ -494,7 +494,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClos if (cosNO <= 0 || cosNI >= 0) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); /* vectors on same side -- not possible */ + return zero_spectrum(); /* vectors on same side -- not possible */ } /* compute half-vector of the refraction (eq. 16) */ float3 ht = -(m_eta * omega_in + I); @@ -530,21 +530,17 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(ccl_private const ShaderClos float out = G * fabsf(cosHI * cosHO) * common; *pdf = G1o * fabsf(cosHO * cosHI) * common; - return make_float3(out, out, out); + return make_spectrum(out); } ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; @@ -588,7 +584,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, if (alpha_x * alpha_y <= 1e-7f) { /* some high number for MIS */ *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); + *eval = make_spectrum(1e6f); bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID); @@ -664,7 +660,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, float common = (G1o * D) * 0.25f / cosNO; *pdf = common; - float3 F = reflection_color(bsdf, *omega_in, m); + Spectrum F = reflection_color(bsdf, *omega_in, m); *eval = G1i * common * F; } @@ -672,14 +668,9 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { *eval *= 0.25f * bsdf->extra->clearcoat; } - -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; - *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; -#endif } else { - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); *pdf = 0.0f; } } @@ -690,39 +681,18 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, /* CAUTION: the i and o variables are inverted relative to the paper * eq. 39 - compute actual refractive direction */ float3 R, T; -#ifdef __RAY_DIFFERENTIALS__ - float3 dRdx, dRdy, dTdx, dTdy; -#endif float m_eta = bsdf->ior, fresnel; bool inside; - fresnel = fresnel_dielectric(m_eta, - m, - I, - &R, - &T, -#ifdef __RAY_DIFFERENTIALS__ - dIdx, - dIdy, - &dRdx, - &dRdy, - &dTdx, - &dTdy, -#endif - &inside); + fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, &inside); if (!inside && fresnel != 1.0f) { - *omega_in = T; -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = dTdx; - *domega_in_dy = dTdy; -#endif if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) { /* some high number for MIS */ *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); + *eval = make_spectrum(1e6f); label = LABEL_TRANSMIT | LABEL_SINGULAR; } else { @@ -750,11 +720,11 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, float out = G1i * fabsf(cosHI * cosHO) * common; *pdf = cosHO * fabsf(cosHI) * common; - *eval = make_float3(out, out, out); + *eval = make_spectrum(out); } } else { - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); *pdf = 0.0f; } } @@ -835,10 +805,10 @@ ccl_device_inline float bsdf_beckmann_aniso_G1( return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); } -ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; float alpha_x = bsdf->alpha_x; @@ -848,7 +818,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(ccl_private const Shader if (m_refractive || alpha_x * alpha_y <= 1e-7f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } float cosNO = dot(N, I); @@ -910,16 +880,16 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(ccl_private const Shader * pdf = pm * 0.25 / dot(m, I); */ *pdf = G1o * common; - return make_float3(out, out, out); + return make_spectrum(out); } - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; float alpha_x = bsdf->alpha_x; @@ -930,7 +900,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const Shade if (!m_refractive || alpha_x * alpha_y <= 1e-7f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } float cosNO = dot(N, I); @@ -938,7 +908,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const Shade if (cosNO <= 0 || cosNI >= 0) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } /* compute half-vector of the refraction (eq. 16) */ float3 ht = -(m_eta * omega_in + I); @@ -971,21 +941,17 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(ccl_private const Shade float out = G * fabsf(cosHI * cosHO) * common; *pdf = G1o * fabsf(cosHO * cosHI) * common; - return make_float3(out, out, out); + return make_spectrum(out); } ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; @@ -1028,7 +994,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, if (alpha_x * alpha_y <= 1e-7f) { /* some high number for MIS */ *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); + *eval = make_spectrum(1e6f); label = LABEL_REFLECT | LABEL_SINGULAR; } else { @@ -1074,16 +1040,11 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, float out = G * common; *pdf = G1o * common; - *eval = make_float3(out, out, out); + *eval = make_spectrum(out); } - -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx; - *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy; -#endif } else { - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); *pdf = 0.0f; } } @@ -1094,39 +1055,18 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, /* CAUTION: the i and o variables are inverted relative to the paper * eq. 39 - compute actual refractive direction */ float3 R, T; -#ifdef __RAY_DIFFERENTIALS__ - float3 dRdx, dRdy, dTdx, dTdy; -#endif float m_eta = bsdf->ior, fresnel; bool inside; - fresnel = fresnel_dielectric(m_eta, - m, - I, - &R, - &T, -#ifdef __RAY_DIFFERENTIALS__ - dIdx, - dIdy, - &dRdx, - &dRdy, - &dTdx, - &dTdy, -#endif - &inside); + fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, &inside); if (!inside && fresnel != 1.0f) { *omega_in = T; -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = dTdx; - *domega_in_dy = dTdy; -#endif - if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) { /* some high number for MIS */ *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); + *eval = make_spectrum(1e6f); label = LABEL_TRANSMIT | LABEL_SINGULAR; } else { @@ -1155,11 +1095,11 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, float out = G * fabsf(cosHI * cosHO) * common; *pdf = G1o * cosHO * fabsf(cosHI) * common; - *eval = make_float3(out, out, out); + *eval = make_spectrum(out); } } else { - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); *pdf = 0.0f; } } diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index b2e068daf17..ac37a648a2c 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -95,29 +95,29 @@ ccl_device_forceinline float3 mf_sample_vndf(const float3 wi, /* Phase function for reflective materials. */ ccl_device_forceinline float3 mf_sample_phase_glossy(const float3 wi, - ccl_private float3 *weight, + ccl_private Spectrum *weight, const float3 wm) { return -wi + 2.0f * wm * dot(wi, wm); } -ccl_device_forceinline float3 mf_eval_phase_glossy(const float3 w, - const float lambda, - const float3 wo, - const float2 alpha) +ccl_device_forceinline Spectrum mf_eval_phase_glossy(const float3 w, + const float lambda, + const float3 wo, + const float2 alpha) { if (w.z > 0.9999f) - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); const float3 wh = normalize(wo - w); if (wh.z < 0.0f) - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z; const float dotW_WH = dot(-w, wh); if (dotW_WH < 0.0f) - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f); if (alpha.x == alpha.y) @@ -125,7 +125,7 @@ ccl_device_forceinline float3 mf_eval_phase_glossy(const float3 w, else phase *= D_ggx_aniso(wh, alpha); - return make_float3(phase, phase, phase); + return make_spectrum(phase); } /* Phase function for dielectric transmissive materials, including both reflection and refraction @@ -148,22 +148,22 @@ ccl_device_forceinline float3 mf_sample_phase_glass(const float3 wi, return normalize(wm * (cosI * inv_eta + cosT) - wi * inv_eta); } -ccl_device_forceinline float3 mf_eval_phase_glass(const float3 w, - const float lambda, - const float3 wo, - const bool wo_outside, - const float2 alpha, - const float eta) +ccl_device_forceinline Spectrum mf_eval_phase_glass(const float3 w, + const float lambda, + const float3 wo, + const bool wo_outside, + const float2 alpha, + const float eta) { if (w.z > 0.9999f) - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z; float v; if (wo_outside) { const float3 wh = normalize(wo - w); if (wh.z < 0.0f) - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); const float dotW_WH = dot(-w, wh); v = fresnel_dielectric_cos(dotW_WH, eta) * max(0.0f, dotW_WH) * D_ggx(wh, alpha.x) * 0.25f / @@ -175,14 +175,14 @@ ccl_device_forceinline float3 mf_eval_phase_glass(const float3 w, wh = -wh; const float dotW_WH = dot(-w, wh), dotWO_WH = dot(wo, wh); if (dotW_WH < 0.0f) - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); float temp = dotW_WH + eta * dotWO_WH; v = (1.0f - fresnel_dielectric_cos(dotW_WH, eta)) * max(0.0f, dotW_WH) * max(0.0f, -dotWO_WH) * D_ggx(wh, alpha.x) / (pArea * temp * temp); } - return make_float3(v, v, v); + return make_spectrum(v); } /* === Utility functions for the random walks === */ @@ -415,27 +415,27 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet return bsdf_microfacet_multi_ggx_common_setup(bsdf); } -ccl_device float3 bsdf_microfacet_multi_ggx_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf, - ccl_private uint *lcg_state) +ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf, + ccl_private uint *lcg_state) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf, - ccl_private uint *lcg_state) +ccl_device Spectrum bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf, + ccl_private uint *lcg_state) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } float3 X, Y, Z; @@ -444,7 +444,7 @@ ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const Shade /* Ensure that the both directions are on the outside w.r.t. the shading normal. */ if (dot(Z, I) <= 0.0f || dot(Z, omega_in) <= 0.0f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID); @@ -478,14 +478,10 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf, ccl_private uint *lcg_state) { @@ -509,11 +505,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, return LABEL_NONE; } *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx; - *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy; -#endif + *eval = make_spectrum(1e6f); return LABEL_REFLECT | LABEL_SINGULAR; } @@ -551,10 +543,6 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x); *eval *= *pdf; -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx; - *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy; -#endif return LABEL_REFLECT | LABEL_GLOSSY; } @@ -588,7 +576,7 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG; } -ccl_device float3 +ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *sc, const float3 I, const float3 omega_in, @@ -599,7 +587,7 @@ bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *s if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } float3 X, Y, Z; @@ -622,17 +610,18 @@ bsdf_microfacet_multi_ggx_glass_eval_transmit(ccl_private const ShaderClosure *s bsdf->extra->color); } -ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf, - ccl_private uint *lcg_state) +ccl_device Spectrum +bsdf_microfacet_multi_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf, + ccl_private uint *lcg_state) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID); @@ -661,14 +650,10 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf, ccl_private uint *lcg_state) { @@ -679,41 +664,17 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { float3 R, T; -#ifdef __RAY_DIFFERENTIALS__ - float3 dRdx, dRdy, dTdx, dTdy; -#endif bool inside; - float fresnel = fresnel_dielectric(bsdf->ior, - Z, - I, - &R, - &T, -#ifdef __RAY_DIFFERENTIALS__ - dIdx, - dIdy, - &dRdx, - &dRdy, - &dTdx, - &dTdy, -#endif - &inside); + float fresnel = fresnel_dielectric(bsdf->ior, Z, I, &R, &T, &inside); *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); + *eval = make_spectrum(1e6f); if (randu < fresnel) { *omega_in = R; -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = dRdx; - *domega_in_dy = dRdy; -#endif return LABEL_REFLECT | LABEL_SINGULAR; } else { *omega_in = T; -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = dTdx; - *domega_in_dy = dTdy; -#endif return LABEL_TRANSMIT | LABEL_SINGULAR; } } @@ -739,22 +700,9 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, *omega_in = X * localO.x + Y * localO.y + Z * localO.z; if (localO.z * localI.z > 0.0f) { -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx; - *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy; -#endif return LABEL_REFLECT | LABEL_GLOSSY; } else { -#ifdef __RAY_DIFFERENTIALS__ - float cosI = dot(Z, I); - float dnp = max(sqrtf(1.0f - (bsdf->ior * bsdf->ior * (1.0f - cosI * cosI))), 1e-7f); - *domega_in_dx = -(bsdf->ior * dIdx) + - ((bsdf->ior - bsdf->ior * bsdf->ior * cosI / dnp) * dot(dIdx, Z)) * Z; - *domega_in_dy = -(bsdf->ior * dIdy) + - ((bsdf->ior - bsdf->ior * bsdf->ior * cosI / dnp) * dot(dIdy, Z)) * Z; -#endif - return LABEL_TRANSMIT | LABEL_GLOSSY; } } diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h index e4fcf0e6ba3..91fb9158050 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h @@ -12,16 +12,16 @@ * multi-scattered energy is used. In combination with MIS, that is enough to produce an unbiased * result, although the balance heuristic isn't necessarily optimal anymore. */ -ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, - float3 wo, - const bool wo_outside, - const float3 color, - const float alpha_x, - const float alpha_y, - ccl_private uint *lcg_state, - const float eta, - bool use_fresnel, - const float3 cspec0) +ccl_device_forceinline Spectrum MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, + float3 wo, + const bool wo_outside, + const Spectrum color, + const float alpha_x, + const float alpha_y, + ccl_private uint *lcg_state, + const float eta, + bool use_fresnel, + const Spectrum cspec0) { /* Evaluating for a shallower incoming direction produces less noise, and the properties of the * BSDF guarantee reciprocity. */ @@ -46,7 +46,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, } if (wi.z < 1e-5f || (wo.z < 1e-5f && wo_outside) || (wo.z > -1e-5f && !wo_outside)) - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); const float2 alpha = make_float2(alpha_x, alpha_y); @@ -54,8 +54,8 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, float shadowing_lambda = mf_lambda(wo_outside ? wo : -wo, alpha); /* Analytically compute single scattering for lower noise. */ - float3 eval; - float3 throughput = make_float3(1.0f, 1.0f, 1.0f); + Spectrum eval; + Spectrum throughput = one_spectrum(); const float3 wh = normalize(wi + wo); #ifdef MF_MULTI_GLASS eval = mf_eval_phase_glass(-wi, lambda_r, wo, wo_outside, alpha, eta); @@ -70,7 +70,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, val *= D_ggx(wh, alpha.x); else val *= D_ggx_aniso(wh, alpha); - eval = make_float3(val, val, val); + eval = make_spectrum(val); #endif float F0 = fresnel_dielectric_cos(1.0f, eta); @@ -99,7 +99,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, #ifdef MF_MULTI_GLASS if (order == 0 && use_fresnel) { /* Evaluate amount of scattering towards wo on this microfacet. */ - float3 phase; + Spectrum phase; if (outside) phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta); else @@ -113,7 +113,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, #endif if (order > 0) { /* Evaluate amount of scattering towards wo on this microfacet. */ - float3 phase; + Spectrum phase; #ifdef MF_MULTI_GLASS if (outside) phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta); @@ -172,19 +172,19 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, * walk escaped the surface in wo. The function returns the throughput between wi and wo. Without * reflection losses due to coloring or fresnel absorption in conductors, the sampling is optimal. */ -ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, - ccl_private float3 *wo, - const float3 color, - const float alpha_x, - const float alpha_y, - ccl_private uint *lcg_state, - const float eta, - bool use_fresnel, - const float3 cspec0) +ccl_device_forceinline Spectrum MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, + ccl_private float3 *wo, + const Spectrum color, + const float alpha_x, + const float alpha_y, + ccl_private uint *lcg_state, + const float eta, + bool use_fresnel, + const Spectrum cspec0) { const float2 alpha = make_float2(alpha_x, alpha_y); - float3 throughput = make_float3(1.0f, 1.0f, 1.0f); + Spectrum throughput = one_spectrum(); float3 wr = -wi; float lambda_r = mf_lambda(wr, alpha); float hr = 1.0f; @@ -229,7 +229,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, throughput *= color; } else { - float3 t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0); + Spectrum t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0); if (order == 0) throughput = t_color; @@ -239,7 +239,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, } #else /* MF_MULTI_GLOSSY */ if (use_fresnel) { - float3 t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0); + Spectrum t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0); if (order == 0) throughput = t_color; @@ -254,7 +254,7 @@ ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, G1_r = mf_G1(wr, C1_r, lambda_r); } *wo = make_float3(0.0f, 0.0f, 1.0f); - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } #undef MF_MULTI_GLASS diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h index 56c7ec869c7..b85390f0676 100644 --- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h +++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h @@ -15,10 +15,10 @@ typedef struct OrenNayarBsdf { static_assert(sizeof(ShaderClosure) >= sizeof(OrenNayarBsdf), "OrenNayarBsdf is too large!"); -ccl_device float3 bsdf_oren_nayar_get_intensity(ccl_private const ShaderClosure *sc, - float3 n, - float3 v, - float3 l) +ccl_device Spectrum bsdf_oren_nayar_get_intensity(ccl_private const ShaderClosure *sc, + float3 n, + float3 v, + float3 l) { ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc; float nl = max(dot(n, l), 0.0f); @@ -28,7 +28,7 @@ ccl_device float3 bsdf_oren_nayar_get_intensity(ccl_private const ShaderClosure if (t > 0.0f) t /= max(nl, nv) + FLT_MIN; float is = nl * (bsdf->a + bsdf->b * t); - return make_float3(is, is, is); + return make_spectrum(is); } ccl_device int bsdf_oren_nayar_setup(ccl_private OrenNayarBsdf *bsdf) @@ -47,10 +47,10 @@ ccl_device int bsdf_oren_nayar_setup(ccl_private OrenNayarBsdf *bsdf) return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc; if (dot(bsdf->N, omega_in) > 0.0f) { @@ -59,30 +59,26 @@ ccl_device float3 bsdf_oren_nayar_eval_reflect(ccl_private const ShaderClosure * } else { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } } -ccl_device float3 bsdf_oren_nayar_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_oren_nayar_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc; @@ -90,16 +86,10 @@ ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc, if (dot(Ng, *omega_in) > 0.0f) { *eval = bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, *omega_in); - -#ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the bounce - *domega_in_dx = (2.0f * dot(bsdf->N, dIdx)) * bsdf->N - dIdx; - *domega_in_dy = (2.0f * dot(bsdf->N, dIdy)) * bsdf->N - dIdy; -#endif } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } return LABEL_REFLECT | LABEL_DIFFUSE; diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h index 74a1f7ae090..4236e77ae6c 100644 --- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h +++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h @@ -8,6 +8,8 @@ #pragma once +#include "kernel/util/color.h" + CCL_NAMESPACE_BEGIN #ifdef __OSL__ @@ -42,10 +44,10 @@ ccl_device int bsdf_phong_ramp_setup(ccl_private PhongRampBsdf *bsdf) return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc; float m_exponent = bsdf->exponent; @@ -61,11 +63,11 @@ ccl_device float3 bsdf_phong_ramp_eval_reflect(ccl_private const ShaderClosure * float common = 0.5f * M_1_PI_F * cosp; float out = cosNI * (m_exponent + 2) * common; *pdf = (m_exponent + 1) * common; - return bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out; + return rgb_to_spectrum(bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out); } } *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device float3 bsdf_phong_ramp_eval_transmit(ccl_private const ShaderClosure *sc, @@ -80,14 +82,10 @@ ccl_device float3 bsdf_phong_ramp_eval_transmit(ccl_private const ShaderClosure ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc; @@ -97,12 +95,6 @@ ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc, if (cosNO > 0) { // reflect the view vector float3 R = (2 * cosNO) * bsdf->N - I; - -# ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx; - *domega_in_dy = (2 * dot(bsdf->N, dIdy)) * bsdf->N - dIdy; -# endif - float3 T, B; make_orthonormals(R, &T, &B); float phi = M_2PI_F * randu; @@ -119,12 +111,12 @@ ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc, float common = 0.5f * M_1_PI_F * cosp; *pdf = (m_exponent + 1) * common; float out = cosNI * (m_exponent + 2) * common; - *eval = bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out; + *eval = rgb_to_spectrum(bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out); } } } else { - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); *pdf = 0.0f; } return LABEL_REFLECT | LABEL_GLOSSY; diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h index 5a7020e82d2..39cca1bd970 100644 --- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h @@ -42,7 +42,7 @@ ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf * return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 +ccl_device Spectrum bsdf_principled_diffuse_compute_brdf(ccl_private const PrincipledDiffuseBsdf *bsdf, float3 N, float3 V, @@ -52,7 +52,7 @@ bsdf_principled_diffuse_compute_brdf(ccl_private const PrincipledDiffuseBsdf *bs const float NdotL = dot(N, L); if (NdotL <= 0) { - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } const float NdotV = dot(N, V); @@ -82,7 +82,7 @@ bsdf_principled_diffuse_compute_brdf(ccl_private const PrincipledDiffuseBsdf *bs float value = M_1_PI_F * NdotL * f; - return make_float3(value, value, value); + return make_spectrum(value); } /* Compute Fresnel at entry point, to be combined with #PRINCIPLED_DIFFUSE_LAMBERT_EXIT @@ -109,10 +109,10 @@ ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf * return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_principled_diffuse_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_principled_diffuse_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc; @@ -126,30 +126,26 @@ ccl_device float3 bsdf_principled_diffuse_eval_reflect(ccl_private const ShaderC } else { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } } -ccl_device float3 bsdf_principled_diffuse_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_principled_diffuse_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc; @@ -160,16 +156,10 @@ ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *s if (dot(Ng, *omega_in) > 0) { *eval = bsdf_principled_diffuse_compute_brdf(bsdf, N, I, *omega_in, pdf); - -#ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx); - *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy); -#endif } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } return LABEL_REFLECT | LABEL_DIFFUSE; } diff --git a/intern/cycles/kernel/closure/bsdf_principled_sheen.h b/intern/cycles/kernel/closure/bsdf_principled_sheen.h index 3a96a93db73..fa46f47eb21 100644 --- a/intern/cycles/kernel/closure/bsdf_principled_sheen.h +++ b/intern/cycles/kernel/closure/bsdf_principled_sheen.h @@ -32,7 +32,7 @@ ccl_device_inline float calculate_avg_principled_sheen_brdf(float3 N, float3 I) return schlick_fresnel(NdotI) * NdotI; } -ccl_device float3 +ccl_device Spectrum calculate_principled_sheen_brdf(float3 N, float3 V, float3 L, float3 H, ccl_private float *pdf) { float NdotL = dot(N, L); @@ -40,14 +40,14 @@ calculate_principled_sheen_brdf(float3 N, float3 V, float3 L, float3 H, ccl_priv if (NdotL < 0 || NdotV < 0) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } float LdotH = dot(L, H); float value = schlick_fresnel(LdotH) * NdotL; - return make_float3(value, value, value); + return make_spectrum(value); } ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd, @@ -59,10 +59,10 @@ ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd, return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc; @@ -77,30 +77,26 @@ ccl_device float3 bsdf_principled_sheen_eval_reflect(ccl_private const ShaderClo } else { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } } -ccl_device float3 bsdf_principled_sheen_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_principled_sheen_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc; @@ -113,15 +109,9 @@ ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc, float3 H = normalize(I + *omega_in); *eval = calculate_principled_sheen_brdf(N, I, *omega_in, H, pdf); - -#ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the diffuse bounce - *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx); - *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy); -#endif } else { - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); *pdf = 0.0f; } return LABEL_REFLECT | LABEL_DIFFUSE; diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h index c8db2b7cf13..5e6c6cdcde6 100644 --- a/intern/cycles/kernel/closure/bsdf_reflection.h +++ b/intern/cycles/kernel/closure/bsdf_reflection.h @@ -18,35 +18,31 @@ ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf) return SD_BSDF; } -ccl_device float3 bsdf_reflection_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_reflection_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_reflection_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_reflection_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; @@ -57,18 +53,14 @@ ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc, if (cosNO > 0) { *omega_in = (2 * cosNO) * N - I; if (dot(Ng, *omega_in) > 0) { -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx; - *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy; -#endif /* Some high number for MIS. */ *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); + *eval = make_spectrum(1e6f); } } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } return LABEL_REFLECT | LABEL_SINGULAR; } diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h index 862e774da87..e680a9617db 100644 --- a/intern/cycles/kernel/closure/bsdf_refraction.h +++ b/intern/cycles/kernel/closure/bsdf_refraction.h @@ -18,35 +18,31 @@ ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf) return SD_BSDF; } -ccl_device float3 bsdf_refraction_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_refraction_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_refraction_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_refraction_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; @@ -54,39 +50,19 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc, float3 N = bsdf->N; float3 R, T; -#ifdef __RAY_DIFFERENTIALS__ - float3 dRdx, dRdy, dTdx, dTdy; -#endif bool inside; float fresnel; - fresnel = fresnel_dielectric(m_eta, - N, - I, - &R, - &T, -#ifdef __RAY_DIFFERENTIALS__ - dIdx, - dIdy, - &dRdx, - &dRdy, - &dTdx, - &dTdy, -#endif - &inside); + fresnel = fresnel_dielectric(m_eta, N, I, &R, &T, &inside); if (!inside && fresnel != 1.0f) { /* Some high number for MIS. */ *pdf = 1e6f; - *eval = make_float3(1e6f, 1e6f, 1e6f); + *eval = make_spectrum(1e6f); *omega_in = T; -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = dTdx; - *domega_in_dy = dTdy; -#endif } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } return LABEL_TRANSMIT | LABEL_SINGULAR; } diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h index 0400fc61860..c9086823de9 100644 --- a/intern/cycles/kernel/closure/bsdf_toon.h +++ b/intern/cycles/kernel/closure/bsdf_toon.h @@ -30,7 +30,7 @@ ccl_device int bsdf_diffuse_toon_setup(ccl_private ToonBsdf *bsdf) return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle) +ccl_device float bsdf_toon_get_intensity(float max_angle, float smooth, float angle) { float is; @@ -41,7 +41,7 @@ ccl_device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float a else is = 0.0f; - return make_float3(is, is, is); + return is; } ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth) @@ -49,48 +49,44 @@ ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth) return fminf(max_angle + smooth, M_PI_2_F); } -ccl_device float3 bsdf_diffuse_toon_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_diffuse_toon_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc; float max_angle = bsdf->size * M_PI_2_F; float smooth = bsdf->smooth * M_PI_2_F; float angle = safe_acosf(fmaxf(dot(bsdf->N, omega_in), 0.0f)); - float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle); + float eval = bsdf_toon_get_intensity(max_angle, smooth, angle); - if (eval.x > 0.0f) { + if (eval > 0.0f) { float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth); *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle)); - return *pdf * eval; + return make_spectrum(*pdf * eval); } *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_diffuse_toon_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_diffuse_toon_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc; @@ -103,21 +99,15 @@ ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc, sample_uniform_cone(bsdf->N, sample_angle, randu, randv, omega_in, pdf); if (dot(Ng, *omega_in) > 0.0f) { - *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle); - -#ifdef __RAY_DIFFERENTIALS__ - // TODO: find a better approximation for the bounce - *domega_in_dx = (2.0f * dot(bsdf->N, dIdx)) * bsdf->N - dIdx; - *domega_in_dy = (2.0f * dot(bsdf->N, dIdy)) * bsdf->N - dIdy; -#endif + *eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle)); } else { - *eval = make_float3(0.f, 0.f, 0.f); + *eval = zero_spectrum(); *pdf = 0.0f; } } else { - *eval = make_float3(0.f, 0.f, 0.f); + *eval = zero_spectrum(); *pdf = 0.0f; } @@ -135,10 +125,10 @@ ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf) return SD_BSDF | SD_BSDF_HAS_EVAL; } -ccl_device float3 bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc; float max_angle = bsdf->size * M_PI_2_F; @@ -153,36 +143,32 @@ ccl_device float3 bsdf_glossy_toon_eval_reflect(ccl_private const ShaderClosure float angle = safe_acosf(fmaxf(cosRI, 0.0f)); - float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle); + float eval = bsdf_toon_get_intensity(max_angle, smooth, angle); float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth); *pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle)); - return *pdf * eval; + return make_spectrum(*pdf * eval); } *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_glossy_toon_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_glossy_toon_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc; @@ -204,21 +190,16 @@ ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc, /* make sure the direction we chose is still in the right hemisphere */ if (cosNI > 0) { - *eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle); - -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx; - *domega_in_dy = (2 * dot(bsdf->N, dIdy)) * bsdf->N - dIdy; -#endif + *eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle)); } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } } else { *pdf = 0.0f; - *eval = make_float3(0.0f, 0.0f, 0.0f); + *eval = zero_spectrum(); } } diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h index 636d9d664f2..c2aee1e1633 100644 --- a/intern/cycles/kernel/closure/bsdf_transparent.h +++ b/intern/cycles/kernel/closure/bsdf_transparent.h @@ -11,7 +11,7 @@ CCL_NAMESPACE_BEGIN ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd, - const float3 weight, + const Spectrum weight, uint32_t path_flag) { /* Check cutoff weight. */ @@ -59,45 +59,37 @@ ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd, } } -ccl_device float3 bsdf_transparent_eval_reflect(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_transparent_eval_reflect(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } -ccl_device float3 bsdf_transparent_eval_transmit(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum bsdf_transparent_eval_transmit(ccl_private const ShaderClosure *sc, + const float3 I, + const float3 omega_in, + ccl_private float *pdf) { *pdf = 0.0f; - return make_float3(0.0f, 0.0f, 0.0f); + return zero_spectrum(); } ccl_device int bsdf_transparent_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { // only one direction is possible *omega_in = -I; -#ifdef __RAY_DIFFERENTIALS__ - *domega_in_dx = -dIdx; - *domega_in_dy = -dIdy; -#endif *pdf = 1; - *eval = make_float3(1, 1, 1); + *eval = one_spectrum(); return LABEL_TRANSMIT | LABEL_TRANSPARENT; } diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h index e3b24d487f1..3c48b98fed9 100644 --- a/intern/cycles/kernel/closure/bsdf_util.h +++ b/intern/cycles/kernel/closure/bsdf_util.h @@ -15,14 +15,6 @@ ccl_device float fresnel_dielectric(float eta, const float3 I, ccl_private float3 *R, ccl_private float3 *T, -#ifdef __RAY_DIFFERENTIALS__ - const float3 dIdx, - const float3 dIdy, - ccl_private float3 *dRdx, - ccl_private float3 *dRdy, - ccl_private float3 *dTdx, - ccl_private float3 *dTdy, -#endif ccl_private bool *is_inside) { float cos = dot(N, I), neta; @@ -45,28 +37,16 @@ ccl_device float fresnel_dielectric(float eta, // compute reflection *R = (2 * cos) * Nn - I; -#ifdef __RAY_DIFFERENTIALS__ - *dRdx = (2 * dot(Nn, dIdx)) * Nn - dIdx; - *dRdy = (2 * dot(Nn, dIdy)) * Nn - dIdy; -#endif float arg = 1 - (neta * neta * (1 - (cos * cos))); if (arg < 0) { *T = make_float3(0.0f, 0.0f, 0.0f); -#ifdef __RAY_DIFFERENTIALS__ - *dTdx = make_float3(0.0f, 0.0f, 0.0f); - *dTdy = make_float3(0.0f, 0.0f, 0.0f); -#endif return 1; // total internal reflection } else { float dnp = max(sqrtf(arg), 1e-7f); float nK = (neta * cos) - dnp; *T = -(neta * I) + (nK * Nn); -#ifdef __RAY_DIFFERENTIALS__ - *dTdx = -(neta * dIdx) + ((neta - neta * neta * cos / dnp) * dot(dIdx, Nn)) * Nn; - *dTdy = -(neta * dIdy) + ((neta - neta * neta * cos / dnp) * dot(dIdy, Nn)) * Nn; -#endif // compute Fresnel terms float cosTheta1 = cos; // N.R float cosTheta2 = -dot(Nn, *T); @@ -110,8 +90,8 @@ ccl_device float schlick_fresnel(float u) } /* Calculate the fresnel color which is a blend between white and the F0 color (cspec0) */ -ccl_device_forceinline float3 -interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0) +ccl_device_forceinline Spectrum +interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, Spectrum cspec0) { /* Calculate the fresnel interpolation factor * The value from fresnel_dielectric_cos(...) has to be normalized because @@ -121,7 +101,7 @@ interpolate_fresnel_color(float3 L, float3 H, float ior, float F0, float3 cspec0 float FH = (fresnel_dielectric_cos(dot(L, H), ior) - F0) * F0_norm; /* Blend between white and a specular color with respect to the fresnel */ - return cspec0 * (1.0f - FH) + make_float3(1.0f, 1.0f, 1.0f) * FH; + return cspec0 * (1.0f - FH) + make_spectrum(FH); } ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N) diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index b87790f5f8a..cdd4d128c1f 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -8,8 +8,8 @@ CCL_NAMESPACE_BEGIN typedef struct Bssrdf { SHADER_CLOSURE_BASE; - float3 radius; - float3 albedo; + Spectrum radius; + Spectrum albedo; float roughness; float anisotropy; } Bssrdf; @@ -69,12 +69,13 @@ ccl_device void bssrdf_setup_radius(ccl_private Bssrdf *bssrdf, const float fourthirdA = (4.0f / 3.0f) * (1.0f + F_dr) / (1.0f - F_dr); /* From Jensen's `Fdr` ratio formula. */ - const float3 alpha_prime = make_float3( - bssrdf_dipole_compute_alpha_prime(bssrdf->albedo.x, fourthirdA), - bssrdf_dipole_compute_alpha_prime(bssrdf->albedo.y, fourthirdA), - bssrdf_dipole_compute_alpha_prime(bssrdf->albedo.z, fourthirdA)); + Spectrum alpha_prime; + FOREACH_SPECTRUM_CHANNEL (i) { + GET_SPECTRUM_CHANNEL(alpha_prime, i) = bssrdf_dipole_compute_alpha_prime( + GET_SPECTRUM_CHANNEL(bssrdf->albedo, i), fourthirdA); + } - bssrdf->radius *= sqrt(3.0f * (one_float3() - alpha_prime)); + bssrdf->radius *= sqrt(3.0f * (one_spectrum() - alpha_prime)); } } @@ -98,7 +99,7 @@ ccl_device_inline float bssrdf_burley_fitting(float A) /* Scale mean free path length so it gives similar looking result * to Cubic and Gaussian models. */ -ccl_device_inline float3 bssrdf_burley_compatible_mfp(float3 r) +ccl_device_inline Spectrum bssrdf_burley_compatible_mfp(Spectrum r) { return 0.25f * M_1_PI_F * r; } @@ -106,11 +107,13 @@ ccl_device_inline float3 bssrdf_burley_compatible_mfp(float3 r) ccl_device void bssrdf_burley_setup(ccl_private Bssrdf *bssrdf) { /* Mean free path length. */ - const float3 l = bssrdf_burley_compatible_mfp(bssrdf->radius); + const Spectrum l = bssrdf_burley_compatible_mfp(bssrdf->radius); /* Surface albedo. */ - const float3 A = bssrdf->albedo; - const float3 s = make_float3( - bssrdf_burley_fitting(A.x), bssrdf_burley_fitting(A.y), bssrdf_burley_fitting(A.z)); + const Spectrum A = bssrdf->albedo; + Spectrum s; + FOREACH_SPECTRUM_CHANNEL (i) { + GET_SPECTRUM_CHANNEL(s, i) = bssrdf_burley_fitting(GET_SPECTRUM_CHANNEL(A, i)); + } bssrdf->radius = l / s; } @@ -198,22 +201,18 @@ ccl_device void bssrdf_burley_sample(const float d, *h = safe_sqrtf(Rm * Rm - r_ * r_); } -ccl_device float bssrdf_num_channels(const float3 radius) +ccl_device float bssrdf_num_channels(const Spectrum radius) { float channels = 0; - if (radius.x > 0.0f) { - channels += 1.0f; - } - if (radius.y > 0.0f) { - channels += 1.0f; - } - if (radius.z > 0.0f) { - channels += 1.0f; + FOREACH_SPECTRUM_CHANNEL (i) { + if (GET_SPECTRUM_CHANNEL(radius, i) > 0.0f) { + channels += 1.0f; + } } return channels; } -ccl_device void bssrdf_sample(const float3 radius, +ccl_device void bssrdf_sample(const Spectrum radius, float xi, ccl_private float *r, ccl_private float *h) @@ -224,39 +223,44 @@ ccl_device void bssrdf_sample(const float3 radius, /* Sample color channel and reuse random number. Only a subset of channels * may be used if their radius was too small to handle as BSSRDF. */ xi *= num_channels; - - if (xi < 1.0f) { - sampled_radius = (radius.x > 0.0f) ? radius.x : (radius.y > 0.0f) ? radius.y : radius.z; - } - else if (xi < 2.0f) { - xi -= 1.0f; - sampled_radius = (radius.x > 0.0f && radius.y > 0.0f) ? radius.y : radius.z; - } - else { - xi -= 2.0f; - sampled_radius = radius.z; + sampled_radius = 0.0f; + + float sum = 0.0f; + FOREACH_SPECTRUM_CHANNEL (i) { + const float channel_radius = GET_SPECTRUM_CHANNEL(radius, i); + if (channel_radius > 0.0f) { + const float next_sum = sum + 1.0f; + if (xi < next_sum) { + xi -= sum; + sampled_radius = channel_radius; + break; + } + sum = next_sum; + } } /* Sample BSSRDF. */ bssrdf_burley_sample(sampled_radius, xi, r, h); } -ccl_device_forceinline float3 bssrdf_eval(const float3 radius, float r) +ccl_device_forceinline Spectrum bssrdf_eval(const Spectrum radius, float r) { - return make_float3(bssrdf_burley_pdf(radius.x, r), - bssrdf_burley_pdf(radius.y, r), - bssrdf_burley_pdf(radius.z, r)); + Spectrum result; + FOREACH_SPECTRUM_CHANNEL (i) { + GET_SPECTRUM_CHANNEL(result, i) = bssrdf_burley_pdf(GET_SPECTRUM_CHANNEL(radius, i), r); + } + return result; } -ccl_device_forceinline float bssrdf_pdf(const float3 radius, float r) +ccl_device_forceinline float bssrdf_pdf(const Spectrum radius, float r) { - float3 pdf = bssrdf_eval(radius, r); - return (pdf.x + pdf.y + pdf.z) / bssrdf_num_channels(radius); + Spectrum pdf = bssrdf_eval(radius, r); + return reduce_add(pdf) / bssrdf_num_channels(radius); } /* Setup */ -ccl_device_inline ccl_private Bssrdf *bssrdf_alloc(ccl_private ShaderData *sd, float3 weight) +ccl_device_inline ccl_private Bssrdf *bssrdf_alloc(ccl_private ShaderData *sd, Spectrum weight) { ccl_private Bssrdf *bssrdf = (ccl_private Bssrdf *)closure_alloc( sd, sizeof(Bssrdf), CLOSURE_NONE_ID, weight); @@ -294,29 +298,19 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd, } /* Verify if the radii are large enough to sample without precision issues. */ - int bssrdf_channels = 3; - float3 diffuse_weight = make_float3(0.0f, 0.0f, 0.0f); - - if (bssrdf->radius.x < BSSRDF_MIN_RADIUS) { - diffuse_weight.x = bssrdf->weight.x; - bssrdf->weight.x = 0.0f; - bssrdf->radius.x = 0.0f; - bssrdf_channels--; - } - if (bssrdf->radius.y < BSSRDF_MIN_RADIUS) { - diffuse_weight.y = bssrdf->weight.y; - bssrdf->weight.y = 0.0f; - bssrdf->radius.y = 0.0f; - bssrdf_channels--; - } - if (bssrdf->radius.z < BSSRDF_MIN_RADIUS) { - diffuse_weight.z = bssrdf->weight.z; - bssrdf->weight.z = 0.0f; - bssrdf->radius.z = 0.0f; - bssrdf_channels--; + int bssrdf_channels = SPECTRUM_CHANNELS; + Spectrum diffuse_weight = zero_spectrum(); + + FOREACH_SPECTRUM_CHANNEL (i) { + if (GET_SPECTRUM_CHANNEL(bssrdf->radius, i) < BSSRDF_MIN_RADIUS) { + GET_SPECTRUM_CHANNEL(diffuse_weight, i) = GET_SPECTRUM_CHANNEL(bssrdf->weight, i); + GET_SPECTRUM_CHANNEL(bssrdf->weight, i) = 0.0f; + GET_SPECTRUM_CHANNEL(bssrdf->radius, i) = 0.0f; + bssrdf_channels--; + } } - if (bssrdf_channels < 3) { + if (bssrdf_channels < SPECTRUM_CHANNELS) { /* Add diffuse BSDF if any radius too small. */ #ifdef __PRINCIPLED__ if (bssrdf->roughness != FLT_MAX) { diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h index 03e19cbde21..d896721f77b 100644 --- a/intern/cycles/kernel/closure/emissive.h +++ b/intern/cycles/kernel/closure/emissive.h @@ -12,7 +12,7 @@ CCL_NAMESPACE_BEGIN /* BACKGROUND CLOSURE */ -ccl_device void background_setup(ccl_private ShaderData *sd, const float3 weight) +ccl_device void background_setup(ccl_private ShaderData *sd, const Spectrum weight) { if (sd->flag & SD_EMISSION) { sd->closure_emission_background += weight; @@ -25,7 +25,7 @@ ccl_device void background_setup(ccl_private ShaderData *sd, const float3 weight /* EMISSION CLOSURE */ -ccl_device void emission_setup(ccl_private ShaderData *sd, const float3 weight) +ccl_device void emission_setup(ccl_private ShaderData *sd, const Spectrum weight) { if (sd->flag & SD_EMISSION) { sd->closure_emission_background += weight; @@ -54,11 +54,11 @@ ccl_device void emissive_sample(const float3 Ng, /* todo: not implemented and used yet */ } -ccl_device float3 emissive_simple_eval(const float3 Ng, const float3 I) +ccl_device Spectrum emissive_simple_eval(const float3 Ng, const float3 I) { float res = emissive_pdf(Ng, I); - return make_float3(res, res, res); + return make_spectrum(res); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h index ef414c7b821..9dbb5154457 100644 --- a/intern/cycles/kernel/closure/volume.h +++ b/intern/cycles/kernel/closure/volume.h @@ -7,7 +7,7 @@ CCL_NAMESPACE_BEGIN /* VOLUME EXTINCTION */ -ccl_device void volume_extinction_setup(ccl_private ShaderData *sd, float3 weight) +ccl_device void volume_extinction_setup(ccl_private ShaderData *sd, Spectrum weight) { if (sd->flag & SD_EXTINCTION) { sd->closure_transparent_extinction += weight; @@ -48,10 +48,10 @@ ccl_device int volume_henyey_greenstein_setup(ccl_private HenyeyGreensteinVolume return SD_SCATTER; } -ccl_device float3 volume_henyey_greenstein_eval_phase(ccl_private const ShaderVolumeClosure *svc, - const float3 I, - float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum volume_henyey_greenstein_eval_phase(ccl_private const ShaderVolumeClosure *svc, + const float3 I, + float3 omega_in, + ccl_private float *pdf) { float g = svc->g; @@ -64,7 +64,7 @@ ccl_device float3 volume_henyey_greenstein_eval_phase(ccl_private const ShaderVo *pdf = single_peaked_henyey_greenstein(cos_theta, g); } - return make_float3(*pdf, *pdf, *pdf); + return make_spectrum(*pdf); } ccl_device float3 @@ -101,37 +101,27 @@ henyey_greenstrein_sample(float3 D, float g, float randu, float randv, ccl_priva ccl_device int volume_henyey_greenstein_sample(ccl_private const ShaderVolumeClosure *svc, float3 I, - float3 dIdx, - float3 dIdy, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private float3 *domega_in_dx, - ccl_private float3 *domega_in_dy, ccl_private float *pdf) { float g = svc->g; /* note that I points towards the viewer and so is used negated */ *omega_in = henyey_greenstrein_sample(-I, g, randu, randv, pdf); - *eval = make_float3(*pdf, *pdf, *pdf); /* perfect importance sampling */ - -#ifdef __RAY_DIFFERENTIALS__ - /* todo: implement ray differential estimation */ - *domega_in_dx = make_float3(0.0f, 0.0f, 0.0f); - *domega_in_dy = make_float3(0.0f, 0.0f, 0.0f); -#endif + *eval = make_spectrum(*pdf); /* perfect importance sampling */ return LABEL_VOLUME_SCATTER; } /* VOLUME CLOSURE */ -ccl_device float3 volume_phase_eval(ccl_private const ShaderData *sd, - ccl_private const ShaderVolumeClosure *svc, - float3 omega_in, - ccl_private float *pdf) +ccl_device Spectrum volume_phase_eval(ccl_private const ShaderData *sd, + ccl_private const ShaderVolumeClosure *svc, + float3 omega_in, + ccl_private float *pdf) { return volume_henyey_greenstein_eval_phase(svc, sd->I, omega_in, pdf); } @@ -140,22 +130,11 @@ ccl_device int volume_phase_sample(ccl_private const ShaderData *sd, ccl_private const ShaderVolumeClosure *svc, float randu, float randv, - ccl_private float3 *eval, + ccl_private Spectrum *eval, ccl_private float3 *omega_in, - ccl_private differential3 *domega_in, ccl_private float *pdf) { - return volume_henyey_greenstein_sample(svc, - sd->I, - sd->dI.dx, - sd->dI.dy, - randu, - randv, - eval, - omega_in, - &domega_in->dx, - &domega_in->dy, - pdf); + return volume_henyey_greenstein_sample(svc, sd->I, randu, randv, eval, omega_in, pdf); } /* Volume sampling utilities. */ @@ -164,45 +143,44 @@ ccl_device int volume_phase_sample(ccl_private const ShaderData *sd, * unnecessary work in volumes and subsurface scattering. */ #define VOLUME_THROUGHPUT_EPSILON 1e-6f -ccl_device float3 volume_color_transmittance(float3 sigma, float t) +ccl_device Spectrum volume_color_transmittance(Spectrum sigma, float t) { return exp(-sigma * t); } -ccl_device float volume_channel_get(float3 value, int channel) +ccl_device float volume_channel_get(Spectrum value, int channel) { - return (channel == 0) ? value.x : ((channel == 1) ? value.y : value.z); + return GET_SPECTRUM_CHANNEL(value, channel); } -ccl_device int volume_sample_channel(float3 albedo, - float3 throughput, +ccl_device int volume_sample_channel(Spectrum albedo, + Spectrum throughput, float rand, - ccl_private float3 *pdf) + ccl_private Spectrum *pdf) { /* Sample color channel proportional to throughput and single scattering * albedo, to significantly reduce noise with many bounce, following: * * "Practical and Controllable Subsurface Scattering for Production Path * Tracing". Matt Jen-Yuan Chiang, Peter Kutz, Brent Burley. SIGGRAPH 2016. */ - float3 weights = fabs(throughput * albedo); - float sum_weights = weights.x + weights.y + weights.z; + Spectrum weights = fabs(throughput * albedo); + float sum_weights = reduce_add(weights); if (sum_weights > 0.0f) { *pdf = weights / sum_weights; } else { - *pdf = make_float3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f); + *pdf = make_spectrum(1.0f / SPECTRUM_CHANNELS); } - if (rand < pdf->x) { - return 0; - } - else if (rand < pdf->x + pdf->y) { - return 1; - } - else { - return 2; + float pdf_sum = 0.0f; + FOREACH_SPECTRUM_CHANNEL (i) { + pdf_sum += GET_SPECTRUM_CHANNEL(*pdf, i); + if (rand < pdf_sum) { + return i; + } } + return SPECTRUM_CHANNELS - 1; } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/device/cpu/compat.h b/intern/cycles/kernel/device/cpu/compat.h index 631e55e0d42..1e3e790ca1f 100644 --- a/intern/cycles/kernel/device/cpu/compat.h +++ b/intern/cycles/kernel/device/cpu/compat.h @@ -33,38 +33,4 @@ CCL_NAMESPACE_BEGIN #define kernel_assert(cond) assert(cond) -/* Macros to handle different memory storage on different devices */ - -#ifdef __KERNEL_SSE2__ -typedef vector3<sseb> sse3b; -typedef vector3<ssef> sse3f; -typedef vector3<ssei> sse3i; - -ccl_device_inline void print_sse3b(const char *label, sse3b &a) -{ - print_sseb(label, a.x); - print_sseb(label, a.y); - print_sseb(label, a.z); -} - -ccl_device_inline void print_sse3f(const char *label, sse3f &a) -{ - print_ssef(label, a.x); - print_ssef(label, a.y); - print_ssef(label, a.z); -} - -ccl_device_inline void print_sse3i(const char *label, sse3i &a) -{ - print_ssei(label, a.x); - print_ssei(label, a.y); - print_ssei(label, a.z); -} - -# if defined(__KERNEL_AVX__) || defined(__KERNEL_AVX2__) -typedef vector3<avxf> avx3f; -# endif - -#endif - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/device/metal/compat.h b/intern/cycles/kernel/device/metal/compat.h index 674de554f61..a04261011f0 100644 --- a/intern/cycles/kernel/device/metal/compat.h +++ b/intern/cycles/kernel/device/metal/compat.h @@ -190,35 +190,46 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \ } volume_write_lambda_pass{kg, this, state}; /* make_type definitions with Metal style element initializers */ -#ifdef make_float2 -# undef make_float2 -#endif -#ifdef make_float3 -# undef make_float3 -#endif -#ifdef make_float4 -# undef make_float4 -#endif -#ifdef make_int2 -# undef make_int2 -#endif -#ifdef make_int3 -# undef make_int3 -#endif -#ifdef make_int4 -# undef make_int4 -#endif -#ifdef make_uchar4 -# undef make_uchar4 -#endif - -#define make_float2(x, y) float2(x, y) -#define make_float3(x, y, z) float3(x, y, z) -#define make_float4(x, y, z, w) float4(x, y, z, w) -#define make_int2(x, y) int2(x, y) -#define make_int3(x, y, z) int3(x, y, z) -#define make_int4(x, y, z, w) int4(x, y, z, w) -#define make_uchar4(x, y, z, w) uchar4(x, y, z, w) +ccl_device_forceinline float2 make_float2(const float x, const float y) +{ + return float2(x, y); +} + +ccl_device_forceinline float3 make_float3(const float x, const float y, const float z) +{ + return float3(x, y, z); +} + +ccl_device_forceinline float4 make_float4(const float x, + const float y, + const float z, + const float w) +{ + return float4(x, y, z, w); +} + +ccl_device_forceinline int2 make_int2(const int x, const int y) +{ + return int2(x, y); +} + +ccl_device_forceinline int3 make_int3(const int x, const int y, const int z) +{ + return int3(x, y, z); +} + +ccl_device_forceinline int4 make_int4(const int x, const int y, const int z, const int w) +{ + return int4(x, y, z, w); +} + +ccl_device_forceinline uchar4 make_uchar4(const uchar x, + const uchar y, + const uchar z, + const uchar w) +{ + return uchar4(x, y, z, w); +} /* Math functions */ diff --git a/intern/cycles/kernel/device/oneapi/compat.h b/intern/cycles/kernel/device/oneapi/compat.h index d8234ee1400..5c49674f247 100644 --- a/intern/cycles/kernel/device/oneapi/compat.h +++ b/intern/cycles/kernel/device/oneapi/compat.h @@ -149,25 +149,13 @@ void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \ /* clang-format on */ /* Types */ + /* It's not possible to use sycl types like sycl::float3, sycl::int3, etc - * because these types have different interfaces from blender version */ + * because these types have different interfaces from blender version. */ using uchar = unsigned char; using sycl::half; -struct float3 { - float x, y, z; -}; - -ccl_always_inline float3 make_float3(float x, float y, float z) -{ - return {x, y, z}; -} -ccl_always_inline float3 make_float3(float x) -{ - return {x, x, x}; -} - /* math functions */ #define fabsf(x) sycl::fabs((x)) #define copysignf(x, y) sycl::copysign((x), (y)) diff --git a/intern/cycles/kernel/film/accumulate.h b/intern/cycles/kernel/film/accumulate.h index 33c35a68ad0..97ec915a8ad 100644 --- a/intern/cycles/kernel/film/accumulate.h +++ b/intern/cycles/kernel/film/accumulate.h @@ -21,10 +21,10 @@ CCL_NAMESPACE_BEGIN ccl_device_inline void bsdf_eval_init(ccl_private BsdfEval *eval, const ClosureType closure_type, - float3 value) + Spectrum value) { - eval->diffuse = zero_float3(); - eval->glossy = zero_float3(); + eval->diffuse = zero_spectrum(); + eval->glossy = zero_spectrum(); if (CLOSURE_IS_BSDF_DIFFUSE(closure_type)) { eval->diffuse = value; @@ -38,7 +38,7 @@ ccl_device_inline void bsdf_eval_init(ccl_private BsdfEval *eval, ccl_device_inline void bsdf_eval_accum(ccl_private BsdfEval *eval, const ClosureType closure_type, - float3 value) + Spectrum value) { if (CLOSURE_IS_BSDF_DIFFUSE(closure_type)) { eval->diffuse += value; @@ -62,26 +62,26 @@ ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float value) eval->sum *= value; } -ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float3 value) +ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, Spectrum value) { eval->diffuse *= value; eval->glossy *= value; eval->sum *= value; } -ccl_device_inline float3 bsdf_eval_sum(ccl_private const BsdfEval *eval) +ccl_device_inline Spectrum bsdf_eval_sum(ccl_private const BsdfEval *eval) { return eval->sum; } -ccl_device_inline float3 bsdf_eval_pass_diffuse_weight(ccl_private const BsdfEval *eval) +ccl_device_inline Spectrum bsdf_eval_pass_diffuse_weight(ccl_private const BsdfEval *eval) { /* Ratio of diffuse weight to recover proportions for writing to render pass. * We assume reflection, transmission and volume scatter to be exclusive. */ return safe_divide(eval->diffuse, eval->sum); } -ccl_device_inline float3 bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval *eval) +ccl_device_inline Spectrum bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval *eval) { /* Ratio of glossy weight to recover proportions for writing to render pass. * We assume reflection, transmission and volume scatter to be exclusive. */ @@ -95,7 +95,9 @@ ccl_device_inline float3 bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval * to render buffers instead of using per-thread memory, and to avoid the * impact of clamping on other contributions. */ -ccl_device_forceinline void kernel_accum_clamp(KernelGlobals kg, ccl_private float3 *L, int bounce) +ccl_device_forceinline void kernel_accum_clamp(KernelGlobals kg, + ccl_private Spectrum *L, + int bounce) { #ifdef __KERNEL_DEBUG_NAN__ if (!isfinite_safe(*L)) { @@ -154,7 +156,7 @@ ccl_device_inline int kernel_accum_sample(KernelGlobals kg, ccl_device void kernel_accum_adaptive_buffer(KernelGlobals kg, const int sample, - const float3 contribution, + const Spectrum contribution, ccl_global float *ccl_restrict buffer) { /* Adaptive Sampling. Fill the additional buffer with the odd samples and calculate our stopping @@ -167,9 +169,13 @@ ccl_device void kernel_accum_adaptive_buffer(KernelGlobals kg, } if (sample_is_even(kernel_data.integrator.sampling_pattern, sample)) { - kernel_write_pass_float4( - buffer + kernel_data.film.pass_adaptive_aux_buffer, - make_float4(contribution.x * 2.0f, contribution.y * 2.0f, contribution.z * 2.0f, 0.0f)); + const float3 contribution_rgb = spectrum_to_rgb(contribution); + + kernel_write_pass_float4(buffer + kernel_data.film.pass_adaptive_aux_buffer, + make_float4(contribution_rgb.x * 2.0f, + contribution_rgb.y * 2.0f, + contribution_rgb.z * 2.0f, + 0.0f)); } } @@ -186,7 +192,7 @@ ccl_device void kernel_accum_adaptive_buffer(KernelGlobals kg, ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg, const uint32_t path_flag, - const float3 contribution, + const Spectrum contribution, ccl_global float *ccl_restrict buffer) { if (!kernel_data.integrator.has_shadow_catcher) { @@ -198,7 +204,7 @@ ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg, /* Matte pass. */ if (kernel_shadow_catcher_is_matte_path(path_flag)) { - kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher_matte, contribution); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_shadow_catcher_matte, contribution); /* NOTE: Accumulate the combined pass and to the samples count pass, so that the adaptive * sampling is based on how noisy the combined pass is as if there were no catchers in the * scene. */ @@ -206,7 +212,7 @@ ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg, /* Shadow catcher pass. */ if (kernel_shadow_catcher_is_object_pass(path_flag)) { - kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher, contribution); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_shadow_catcher, contribution); return true; } @@ -215,7 +221,7 @@ ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg, ccl_device bool kernel_accum_shadow_catcher_transparent(KernelGlobals kg, const uint32_t path_flag, - const float3 contribution, + const Spectrum contribution, const float transparent, ccl_global float *ccl_restrict buffer) { @@ -232,9 +238,11 @@ ccl_device bool kernel_accum_shadow_catcher_transparent(KernelGlobals kg, /* Matte pass. */ if (kernel_shadow_catcher_is_matte_path(path_flag)) { + const float3 contribution_rgb = spectrum_to_rgb(contribution); + kernel_write_pass_float4( buffer + kernel_data.film.pass_shadow_catcher_matte, - make_float4(contribution.x, contribution.y, contribution.z, transparent)); + make_float4(contribution_rgb.x, contribution_rgb.y, contribution_rgb.z, transparent)); /* NOTE: Accumulate the combined pass and to the samples count pass, so that the adaptive * sampling is based on how noisy the combined pass is as if there were no catchers in the * scene. */ @@ -245,7 +253,7 @@ ccl_device bool kernel_accum_shadow_catcher_transparent(KernelGlobals kg, /* NOTE: The transparency of the shadow catcher pass is ignored. It is not needed for the * calculation and the alpha channel of the pass contains numbers of samples contributed to a * pixel of the pass. */ - kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher, contribution); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_shadow_catcher, contribution); return true; } @@ -279,7 +287,7 @@ ccl_device void kernel_accum_shadow_catcher_transparent_only(KernelGlobals kg, ccl_device_inline void kernel_accum_combined_pass(KernelGlobals kg, const uint32_t path_flag, const int sample, - const float3 contribution, + const Spectrum contribution, ccl_global float *ccl_restrict buffer) { #ifdef __SHADOW_CATCHER__ @@ -289,7 +297,7 @@ ccl_device_inline void kernel_accum_combined_pass(KernelGlobals kg, #endif if (kernel_data.film.light_pass_flag & PASSMASK(COMBINED)) { - kernel_write_pass_float3(buffer + kernel_data.film.pass_combined, contribution); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_combined, contribution); } kernel_accum_adaptive_buffer(kg, sample, contribution, buffer); @@ -299,7 +307,7 @@ ccl_device_inline void kernel_accum_combined_pass(KernelGlobals kg, ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg, const uint32_t path_flag, const int sample, - const float3 contribution, + const Spectrum contribution, const float transparent, ccl_global float *ccl_restrict buffer) @@ -311,9 +319,11 @@ ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg, #endif if (kernel_data.film.light_pass_flag & PASSMASK(COMBINED)) { + const float3 contribution_rgb = spectrum_to_rgb(contribution); + kernel_write_pass_float4( buffer + kernel_data.film.pass_combined, - make_float4(contribution.x, contribution.y, contribution.z, transparent)); + make_float4(contribution_rgb.x, contribution_rgb.y, contribution_rgb.z, transparent)); } kernel_accum_adaptive_buffer(kg, sample, contribution, buffer); @@ -323,7 +333,7 @@ ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg, ccl_device_inline void kernel_accum_emission_or_background_pass( KernelGlobals kg, ConstIntegratorState state, - float3 contribution, + Spectrum contribution, ccl_global float *ccl_restrict buffer, const int pass, const int lightgroup = LIGHTGROUP_NONE) @@ -340,17 +350,18 @@ ccl_device_inline void kernel_accum_emission_or_background_pass( # ifdef __DENOISING_FEATURES__ if (path_flag & PATH_RAY_DENOISING_FEATURES) { if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) { - const float3 denoising_feature_throughput = INTEGRATOR_STATE( + const Spectrum denoising_feature_throughput = INTEGRATOR_STATE( state, path, denoising_feature_throughput); - const float3 denoising_albedo = denoising_feature_throughput * contribution; - kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo); + const Spectrum denoising_albedo = denoising_feature_throughput * contribution; + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo, + denoising_albedo); } } # endif /* __DENOISING_FEATURES__ */ if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) { - kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, - contribution); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, + contribution); } if (!(path_flag & PATH_RAY_ANY_PASS)) { @@ -366,15 +377,15 @@ ccl_device_inline void kernel_accum_emission_or_background_pass( if (path_flag & PATH_RAY_SURFACE_PASS) { /* Indirectly visible through reflection. */ - const float3 diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight); - const float3 glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight); + const Spectrum diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight); + const Spectrum glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight); /* Glossy */ const int glossy_pass_offset = ((INTEGRATOR_STATE(state, path, bounce) == 1) ? kernel_data.film.pass_glossy_direct : kernel_data.film.pass_glossy_indirect); if (glossy_pass_offset != PASS_UNUSED) { - kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_weight * contribution); + kernel_write_pass_spectrum(buffer + glossy_pass_offset, glossy_weight * contribution); } /* Transmission */ @@ -385,9 +396,9 @@ ccl_device_inline void kernel_accum_emission_or_background_pass( if (transmission_pass_offset != PASS_UNUSED) { /* Transmission is what remains if not diffuse and glossy, not stored explicitly to save * GPU memory. */ - const float3 transmission_weight = one_float3() - diffuse_weight - glossy_weight; - kernel_write_pass_float3(buffer + transmission_pass_offset, - transmission_weight * contribution); + const Spectrum transmission_weight = one_spectrum() - diffuse_weight - glossy_weight; + kernel_write_pass_spectrum(buffer + transmission_pass_offset, + transmission_weight * contribution); } /* Reconstruct diffuse subset of throughput. */ @@ -408,7 +419,7 @@ ccl_device_inline void kernel_accum_emission_or_background_pass( /* Single write call for GPU coherence. */ if (pass_offset != PASS_UNUSED) { - kernel_write_pass_float3(buffer + pass_offset, contribution); + kernel_write_pass_spectrum(buffer + pass_offset, contribution); } #endif /* __PASSES__ */ } @@ -419,7 +430,7 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, ccl_global float *ccl_restrict render_buffer) { /* The throughput for shadow paths already contains the light shader evaluation. */ - float3 contribution = INTEGRATOR_STATE(state, shadow_path, throughput); + Spectrum contribution = INTEGRATOR_STATE(state, shadow_path, throughput); kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, shadow_path, bounce)); const uint32_t render_pixel_index = INTEGRATOR_STATE(state, shadow_path, render_pixel_index); @@ -433,10 +444,10 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, /* Ambient occlusion. */ if (path_flag & PATH_RAY_SHADOW_FOR_AO) { if ((kernel_data.kernel_features & KERNEL_FEATURE_AO_PASS) && (path_flag & PATH_RAY_CAMERA)) { - kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, contribution); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_ao, contribution); } if (kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) { - const float3 ao_weight = INTEGRATOR_STATE(state, shadow_path, unshadowed_throughput); + const Spectrum ao_weight = INTEGRATOR_STATE(state, shadow_path, unshadowed_throughput); kernel_accum_combined_pass(kg, path_flag, sample, contribution * ao_weight, buffer); } return; @@ -458,8 +469,8 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, /* Write lightgroup pass. LIGHTGROUP_NONE is ~0 so decode from unsigned to signed */ const int lightgroup = (int)(INTEGRATOR_STATE(state, shadow_path, lightgroup)) - 1; if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) { - kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, - contribution); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, + contribution); } if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { @@ -467,15 +478,15 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, if (path_flag & PATH_RAY_SURFACE_PASS) { /* Indirectly visible through reflection. */ - const float3 diffuse_weight = INTEGRATOR_STATE(state, shadow_path, pass_diffuse_weight); - const float3 glossy_weight = INTEGRATOR_STATE(state, shadow_path, pass_glossy_weight); + const Spectrum diffuse_weight = INTEGRATOR_STATE(state, shadow_path, pass_diffuse_weight); + const Spectrum glossy_weight = INTEGRATOR_STATE(state, shadow_path, pass_glossy_weight); /* Glossy */ const int glossy_pass_offset = ((INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ? kernel_data.film.pass_glossy_direct : kernel_data.film.pass_glossy_indirect); if (glossy_pass_offset != PASS_UNUSED) { - kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_weight * contribution); + kernel_write_pass_spectrum(buffer + glossy_pass_offset, glossy_weight * contribution); } /* Transmission */ @@ -486,9 +497,9 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, if (transmission_pass_offset != PASS_UNUSED) { /* Transmission is what remains if not diffuse and glossy, not stored explicitly to save * GPU memory. */ - const float3 transmission_weight = one_float3() - diffuse_weight - glossy_weight; - kernel_write_pass_float3(buffer + transmission_pass_offset, - transmission_weight * contribution); + const Spectrum transmission_weight = one_spectrum() - diffuse_weight - glossy_weight; + kernel_write_pass_spectrum(buffer + transmission_pass_offset, + transmission_weight * contribution); } /* Reconstruct diffuse subset of throughput. */ @@ -508,19 +519,19 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg, /* Single write call for GPU coherence. */ if (pass_offset != PASS_UNUSED) { - kernel_write_pass_float3(buffer + pass_offset, contribution); + kernel_write_pass_spectrum(buffer + pass_offset, contribution); } } /* Write shadow pass. */ if (kernel_data.film.pass_shadow != PASS_UNUSED && (path_flag & PATH_RAY_SHADOW_FOR_LIGHT) && (path_flag & PATH_RAY_TRANSPARENT_BACKGROUND)) { - const float3 unshadowed_throughput = INTEGRATOR_STATE( + const Spectrum unshadowed_throughput = INTEGRATOR_STATE( state, shadow_path, unshadowed_throughput); - const float3 shadowed_throughput = INTEGRATOR_STATE(state, shadow_path, throughput); - const float3 shadow = safe_divide(shadowed_throughput, unshadowed_throughput) * - kernel_data.film.pass_shadow_scale; - kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow, shadow); + const Spectrum shadowed_throughput = INTEGRATOR_STATE(state, shadow_path, throughput); + const Spectrum shadow = safe_divide(shadowed_throughput, unshadowed_throughput) * + kernel_data.film.pass_shadow_scale; + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_shadow, shadow); } } #endif @@ -560,12 +571,12 @@ ccl_device_inline void kernel_accum_holdout(KernelGlobals kg, * Includes transparency, matching kernel_accum_transparent. */ ccl_device_inline void kernel_accum_background(KernelGlobals kg, ConstIntegratorState state, - const float3 L, + const Spectrum L, const float transparent, const bool is_transparent_background_ray, ccl_global float *ccl_restrict render_buffer) { - float3 contribution = float3(INTEGRATOR_STATE(state, path, throughput)) * L; + Spectrum contribution = INTEGRATOR_STATE(state, path, throughput) * L; kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1); ccl_global float *buffer = kernel_accum_pixel_render_buffer(kg, state, render_buffer); @@ -590,11 +601,11 @@ ccl_device_inline void kernel_accum_background(KernelGlobals kg, /* Write emission to render buffer. */ ccl_device_inline void kernel_accum_emission(KernelGlobals kg, ConstIntegratorState state, - const float3 L, + const Spectrum L, ccl_global float *ccl_restrict render_buffer, const int lightgroup = LIGHTGROUP_NONE) { - float3 contribution = L; + Spectrum contribution = L; kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1); ccl_global float *buffer = kernel_accum_pixel_render_buffer(kg, state, render_buffer); diff --git a/intern/cycles/kernel/film/passes.h b/intern/cycles/kernel/film/passes.h index 1f5cf2048f1..bea23411000 100644 --- a/intern/cycles/kernel/film/passes.h +++ b/intern/cycles/kernel/film/passes.h @@ -40,7 +40,7 @@ ccl_device_forceinline void kernel_write_denoising_features_surface( ccl_global float *buffer = kernel_pass_pixel_render_buffer(kg, state, render_buffer); if (kernel_data.film.pass_denoising_depth != PASS_UNUSED) { - const float3 denoising_feature_throughput = INTEGRATOR_STATE( + const Spectrum denoising_feature_throughput = INTEGRATOR_STATE( state, path, denoising_feature_throughput); const float denoising_depth = ensure_finite(average(denoising_feature_throughput) * sd->ray_length); @@ -48,8 +48,8 @@ ccl_device_forceinline void kernel_write_denoising_features_surface( } float3 normal = zero_float3(); - float3 diffuse_albedo = zero_float3(); - float3 specular_albedo = zero_float3(); + Spectrum diffuse_albedo = zero_spectrum(); + Spectrum specular_albedo = zero_spectrum(); float sum_weight = 0.0f, sum_nonspecular_weight = 0.0f; for (int i = 0; i < sd->num_closure; i++) { @@ -63,7 +63,7 @@ ccl_device_forceinline void kernel_write_denoising_features_surface( normal += sc->N * sc->sample_weight; sum_weight += sc->sample_weight; - float3 closure_albedo = sc->weight; + Spectrum closure_albedo = sc->weight; /* Closures that include a Fresnel term typically have weights close to 1 even though their * actual contribution is significantly lower. * To account for this, we scale their weight by the average fresnel factor (the same is also @@ -113,10 +113,12 @@ ccl_device_forceinline void kernel_write_denoising_features_surface( } if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) { - const float3 denoising_feature_throughput = INTEGRATOR_STATE( + const Spectrum denoising_feature_throughput = INTEGRATOR_STATE( state, path, denoising_feature_throughput); - const float3 denoising_albedo = ensure_finite(denoising_feature_throughput * diffuse_albedo); - kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo); + const Spectrum denoising_albedo = ensure_finite(denoising_feature_throughput * + diffuse_albedo); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo, + denoising_albedo); } INTEGRATOR_STATE_WRITE(state, path, flag) &= ~PATH_RAY_DENOISING_FEATURES; @@ -128,13 +130,13 @@ ccl_device_forceinline void kernel_write_denoising_features_surface( ccl_device_forceinline void kernel_write_denoising_features_volume(KernelGlobals kg, IntegratorState state, - const float3 albedo, + const Spectrum albedo, const bool scatter, ccl_global float *ccl_restrict render_buffer) { ccl_global float *buffer = kernel_pass_pixel_render_buffer(kg, state, render_buffer); - const float3 denoising_feature_throughput = INTEGRATOR_STATE( + const Spectrum denoising_feature_throughput = INTEGRATOR_STATE( state, path, denoising_feature_throughput); if (scatter && kernel_data.film.pass_denoising_normal != PASS_UNUSED) { @@ -148,8 +150,8 @@ ccl_device_forceinline void kernel_write_denoising_features_volume(KernelGlobals if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) { /* Write albedo. */ - const float3 denoising_albedo = ensure_finite(denoising_feature_throughput * albedo); - kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo); + const Spectrum denoising_albedo = ensure_finite(denoising_feature_throughput * albedo); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo); } } #endif /* __DENOISING_FEATURES__ */ @@ -228,7 +230,7 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals kg, } if (kernel_data.film.cryptomatte_passes) { - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); const float matte_weight = average(throughput) * (1.0f - average(shader_bsdf_transparency(kg, sd))); if (matte_weight > 0.0f) { @@ -252,19 +254,19 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals kg, } if (flag & PASSMASK(DIFFUSE_COLOR)) { - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); - kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color, - shader_bsdf_diffuse(kg, sd) * throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_diffuse_color, + shader_bsdf_diffuse(kg, sd) * throughput); } if (flag & PASSMASK(GLOSSY_COLOR)) { - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); - kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, - shader_bsdf_glossy(kg, sd) * throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_glossy_color, + shader_bsdf_glossy(kg, sd) * throughput); } if (flag & PASSMASK(TRANSMISSION_COLOR)) { - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); - kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, - shader_bsdf_transmission(kg, sd) * throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); + kernel_write_pass_spectrum(buffer + kernel_data.film.pass_transmission_color, + shader_bsdf_transmission(kg, sd) * throughput); } if (flag & PASSMASK(MIST)) { /* Bring depth into 0..1 range. */ @@ -287,8 +289,8 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals kg, mist = powf(mist, mist_falloff); /* Modulate by transparency */ - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); - const float3 alpha = shader_bsdf_alpha(kg, sd); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum alpha = shader_bsdf_alpha(kg, sd); const float mist_output = (1.0f - mist) * average(throughput * alpha); /* Note that the final value in the render buffer we want is 1 - mist_output, diff --git a/intern/cycles/kernel/film/write_passes.h b/intern/cycles/kernel/film/write_passes.h index 9148d73518f..c78116cedc6 100644 --- a/intern/cycles/kernel/film/write_passes.h +++ b/intern/cycles/kernel/film/write_passes.h @@ -3,6 +3,8 @@ #pragma once +#include "kernel/util/color.h" + #ifdef __KERNEL_GPU__ # define __ATOMIC_PASS_WRITE__ #endif @@ -36,6 +38,12 @@ ccl_device_inline void kernel_write_pass_float3(ccl_global float *ccl_restrict b #endif } +ccl_device_inline void kernel_write_pass_spectrum(ccl_global float *ccl_restrict buffer, + Spectrum value) +{ + kernel_write_pass_float3(buffer, spectrum_to_rgb(value)); +} + ccl_device_inline void kernel_write_pass_float4(ccl_global float *ccl_restrict buffer, float4 value) { diff --git a/intern/cycles/kernel/geom/shader_data.h b/intern/cycles/kernel/geom/shader_data.h index 5af89b45f20..028c03ace1d 100644 --- a/intern/cycles/kernel/geom/shader_data.h +++ b/intern/cycles/kernel/geom/shader_data.h @@ -123,9 +123,9 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, #ifdef __RAY_DIFFERENTIALS__ /* differentials */ - differential_transfer_compact(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, sd->ray_length); - differential_incoming_compact(&sd->dI, ray->D, ray->dD); - differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng); + sd->dP = differential_transfer_compact(ray->dP, ray->D, ray->dD, sd->ray_length); + sd->dI = differential_incoming_compact(ray->dD); + differential_dudv_compact(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng); #endif } @@ -240,8 +240,8 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg, #ifdef __RAY_DIFFERENTIALS__ /* no ray differentials here yet */ - sd->dP = differential3_zero(); - sd->dI = differential3_zero(); + sd->dP = differential_zero_compact(); + sd->dI = differential_zero_compact(); sd->du = differential_zero(); sd->dv = differential_zero(); #endif @@ -348,8 +348,8 @@ ccl_device void shader_setup_from_curve(KernelGlobals kg, /* No ray differentials currently. */ #ifdef __RAY_DIFFERENTIALS__ - sd->dP = differential3_zero(); - sd->dI = differential3_zero(); + sd->dP = differential_zero_compact(); + sd->dI = differential_zero_compact(); sd->du = differential_zero(); sd->dv = differential_zero(); #endif @@ -391,8 +391,8 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals kg, #ifdef __RAY_DIFFERENTIALS__ /* differentials */ - sd->dP = differential3_zero(); /* TODO: ray->dP */ - differential_incoming(&sd->dI, sd->dP); + sd->dP = differential_zero_compact(); /* TODO: ray->dP */ + sd->dI = differential_zero_compact(); sd->du = differential_zero(); sd->dv = differential_zero(); #endif @@ -433,8 +433,8 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals kg, # ifdef __RAY_DIFFERENTIALS__ /* differentials */ - sd->dP = differential3_zero(); /* TODO ray->dD */ - differential_incoming(&sd->dI, sd->dP); + sd->dP = differential_zero_compact(); /* TODO ray->dD */ + sd->dI = differential_zero_compact(); sd->du = differential_zero(); sd->dv = differential_zero(); # endif diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index aa72b93c9d2..c95f1557f04 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -392,7 +392,7 @@ ccl_device_forceinline bool mnee_compute_constraint_derivatives( /* Invert (block) constraint derivative matrix and solve linear system so we can map dh back to dx: * dh / dx = A * dx = inverse(A) x dh - * to use for specular specular manifold walk + * to use for specular manifold walk * (See for example http://faculty.washington.edu/finlayso/ebook/algebraic/advanced/LUtri.htm * for block tridiagonal matrix based linear system solve) */ ccl_device_forceinline bool mnee_solve_matrix_h_to_x(int vertex_count, @@ -634,9 +634,9 @@ mnee_sample_bsdf_dh(ClosureType type, float alpha_x, float alpha_y, float sample * We assume here that the pdf (in half-vector measure) is the same as * the one calculation when sampling the microfacet normals from the * specular chain above: this allows us to simplify the bsdf weight */ -ccl_device_forceinline float3 mnee_eval_bsdf_contribution(ccl_private ShaderClosure *closure, - float3 wi, - float3 wo) +ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderClosure *closure, + float3 wi, + float3 wo) { ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)closure; @@ -835,7 +835,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg, 1; INTEGRATOR_STATE_WRITE(state, path, bounce) = bounce + vertex_count; - float3 light_eval = light_sample_shader_eval(kg, state, sd_mnee, ls, sd->time); + Spectrum light_eval = light_sample_shader_eval(kg, state, sd_mnee, ls, sd->time); bsdf_eval_mul(throughput, light_eval / ls->pdf); /* Generalized geometry term. */ @@ -924,7 +924,7 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg, /* Evaluate product term inside eq.6 at solution interface. vi * divided by corresponding sampled pdf: * fr(vi)_do / pdf_dh(vi) x |do/dh| x |n.wo / n.h| */ - float3 bsdf_contribution = mnee_eval_bsdf_contribution(v.bsdf, wi, wo); + Spectrum bsdf_contribution = mnee_eval_bsdf_contribution(v.bsdf, wi, wo); bsdf_eval_mul(throughput, bsdf_contribution); } diff --git a/intern/cycles/kernel/integrator/path_state.h b/intern/cycles/kernel/integrator/path_state.h index b09bc117d78..a41e922b593 100644 --- a/intern/cycles/kernel/integrator/path_state.h +++ b/intern/cycles/kernel/integrator/path_state.h @@ -54,7 +54,7 @@ ccl_device_inline void path_state_init_integrator(KernelGlobals kg, INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = 0.0f; INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = FLT_MAX; INTEGRATOR_STATE_WRITE(state, path, continuation_probability) = 1.0f; - INTEGRATOR_STATE_WRITE(state, path, throughput) = make_float3(1.0f, 1.0f, 1.0f); + INTEGRATOR_STATE_WRITE(state, path, throughput) = one_spectrum(); #ifdef __MNEE__ INTEGRATOR_STATE_WRITE(state, path, mnee) = 0; @@ -74,7 +74,7 @@ ccl_device_inline void path_state_init_integrator(KernelGlobals kg, #ifdef __DENOISING_FEATURES__ if (kernel_data.kernel_features & KERNEL_FEATURE_DENOISING) { INTEGRATOR_STATE_WRITE(state, path, flag) |= PATH_RAY_DENOISING_FEATURES; - INTEGRATOR_STATE_WRITE(state, path, denoising_feature_throughput) = one_float3(); + INTEGRATOR_STATE_WRITE(state, path, denoising_feature_throughput) = one_spectrum(); } #endif } @@ -321,8 +321,10 @@ ccl_device_inline float path_state_rng_1D_hash(KernelGlobals kg, /* Use a hash instead of dimension, this is not great but avoids adding * more dimensions to each bounce which reduces quality of dimensions we * are already using. */ - return path_rng_1D( - kg, cmj_hash_simple(rng_state->rng_hash, hash), rng_state->sample, rng_state->rng_offset); + return path_rng_1D(kg, + hash_wang_seeded_uint(rng_state->rng_hash, hash), + rng_state->sample, + rng_state->rng_offset); } ccl_device_inline float path_branched_rng_1D(KernelGlobals kg, diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h index a7edfffd175..57d060d58df 100644 --- a/intern/cycles/kernel/integrator/shade_background.h +++ b/intern/cycles/kernel/integrator/shade_background.h @@ -10,9 +10,9 @@ CCL_NAMESPACE_BEGIN -ccl_device float3 integrator_eval_background_shader(KernelGlobals kg, - IntegratorState state, - ccl_global float *ccl_restrict render_buffer) +ccl_device Spectrum integrator_eval_background_shader(KernelGlobals kg, + IntegratorState state, + ccl_global float *ccl_restrict render_buffer) { #ifdef __BACKGROUND__ const int shader = kernel_data.background.surface_shader; @@ -26,11 +26,11 @@ ccl_device float3 integrator_eval_background_shader(KernelGlobals kg, ((shader & SHADER_EXCLUDE_TRANSMIT) && (path_flag & PATH_RAY_TRANSMIT)) || ((shader & SHADER_EXCLUDE_CAMERA) && (path_flag & PATH_RAY_CAMERA)) || ((shader & SHADER_EXCLUDE_SCATTER) && (path_flag & PATH_RAY_VOLUME_SCATTER))) - return zero_float3(); + return zero_spectrum(); } /* Use fast constant background color if available. */ - float3 L = zero_float3(); + Spectrum L = zero_spectrum(); if (!shader_constant_emission_eval(kg, shader, &L)) { /* Evaluate background shader. */ @@ -73,7 +73,7 @@ ccl_device float3 integrator_eval_background_shader(KernelGlobals kg, return L; #else - return make_float3(0.8f, 0.8f, 0.8f); + return make_spectrum(0.8f); #endif } @@ -117,8 +117,8 @@ ccl_device_inline void integrate_background(KernelGlobals kg, #endif /* __MNEE__ */ /* Evaluate background shader. */ - float3 L = (eval_background) ? integrator_eval_background_shader(kg, state, render_buffer) : - zero_float3(); + Spectrum L = (eval_background) ? integrator_eval_background_shader(kg, state, render_buffer) : + zero_spectrum(); /* When using the ao bounces approximation, adjust background * shader intensity with ao factor. */ @@ -169,7 +169,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg, /* TODO: does aliasing like this break automatic SoA in CUDA? */ ShaderDataTinyStorage emission_sd_storage; ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage); - float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time); + Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time); if (is_zero(light_eval)) { return; } @@ -184,7 +184,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg, } /* Write to render buffer. */ - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); kernel_accum_emission( kg, state, throughput * light_eval, render_buffer, kernel_data.background.lightgroup); } diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h index 910e3383f51..ac9d1415abb 100644 --- a/intern/cycles/kernel/integrator/shade_light.h +++ b/intern/cycles/kernel/integrator/shade_light.h @@ -51,7 +51,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg, /* TODO: does aliasing like this break automatic SoA in CUDA? */ ShaderDataTinyStorage emission_sd_storage; ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage); - float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time); + Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, ray_time); if (is_zero(light_eval)) { return; } @@ -66,7 +66,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg, } /* Write to render buffer. */ - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); kernel_accum_emission(kg, state, throughput * light_eval, render_buffer, ls.group); } diff --git a/intern/cycles/kernel/integrator/shade_shadow.h b/intern/cycles/kernel/integrator/shade_shadow.h index 4b002a47bee..a52706a77f1 100644 --- a/intern/cycles/kernel/integrator/shade_shadow.h +++ b/intern/cycles/kernel/integrator/shade_shadow.h @@ -15,9 +15,9 @@ ccl_device_inline bool shadow_intersections_has_remaining(const uint num_hits) } #ifdef __TRANSPARENT_SHADOWS__ -ccl_device_inline float3 integrate_transparent_surface_shadow(KernelGlobals kg, - IntegratorShadowState state, - const int hit) +ccl_device_inline Spectrum integrate_transparent_surface_shadow(KernelGlobals kg, + IntegratorShadowState state, + const int hit) { PROFILING_INIT(kg, PROFILING_SHADE_SHADOW_SURFACE); @@ -58,7 +58,7 @@ ccl_device_inline void integrate_transparent_volume_shadow(KernelGlobals kg, IntegratorShadowState state, const int hit, const int num_recorded_hits, - ccl_private float3 *ccl_restrict + ccl_private Spectrum *ccl_restrict throughput) { PROFILING_INIT(kg, PROFILING_SHADE_SHADOW_VOLUME); @@ -100,7 +100,7 @@ ccl_device_inline bool integrate_transparent_shadow(KernelGlobals kg, if (hit < num_recorded_hits || !shadow_intersections_has_remaining(num_hits)) { # ifdef __VOLUME__ if (!integrator_state_shadow_volume_stack_is_empty(kg, state)) { - float3 throughput = INTEGRATOR_STATE(state, shadow_path, throughput); + Spectrum throughput = INTEGRATOR_STATE(state, shadow_path, throughput); integrate_transparent_volume_shadow(kg, state, hit, num_recorded_hits, &throughput); if (is_zero(throughput)) { return true; @@ -113,8 +113,8 @@ ccl_device_inline bool integrate_transparent_shadow(KernelGlobals kg, /* Surface shaders. */ if (hit < num_recorded_hits) { - const float3 shadow = integrate_transparent_surface_shadow(kg, state, hit); - const float3 throughput = INTEGRATOR_STATE(state, shadow_path, throughput) * shadow; + const Spectrum shadow = integrate_transparent_surface_shadow(kg, state, hit); + const Spectrum throughput = INTEGRATOR_STATE(state, shadow_path, throughput) * shadow; if (is_zero(throughput)) { return true; } diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 59c59e9224a..f42e2979b3b 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -88,11 +88,11 @@ ccl_device_forceinline bool integrate_surface_holdout(KernelGlobals kg, if (((sd->flag & SD_HOLDOUT) || (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) && (path_flag & PATH_RAY_TRANSPARENT_BACKGROUND)) { - const float3 holdout_weight = shader_holdout_apply(kg, sd); - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum holdout_weight = shader_holdout_apply(kg, sd); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); const float transparent = average(holdout_weight * throughput); kernel_accum_holdout(kg, state, path_flag, transparent, render_buffer); - if (isequal(holdout_weight, one_float3())) { + if (isequal(holdout_weight, one_spectrum())) { return false; } } @@ -111,7 +111,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); /* Evaluate emissive closure. */ - float3 L = shader_emissive_eval(sd); + Spectrum L = shader_emissive_eval(sd); # ifdef __HAIR__ if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && @@ -130,7 +130,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, L *= mis_weight; } - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); kernel_accum_emission( kg, state, throughput * L, render_buffer, object_lightgroup(kg, sd->object)); } @@ -207,7 +207,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, else # endif /* __MNEE__ */ { - const float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, sd->time); + const Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, sd->time); if (is_zero(light_eval)) { return; } @@ -261,11 +261,12 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, /* Copy state from main path to shadow path. */ uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag); shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0; - const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * bsdf_eval_sum(&bsdf_eval); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput) * + bsdf_eval_sum(&bsdf_eval); if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { - packed_float3 pass_diffuse_weight; - packed_float3 pass_glossy_weight; + PackedSpectrum pass_diffuse_weight; + PackedSpectrum pass_glossy_weight; if (shadow_flag & PATH_RAY_ANY_PASS) { /* Indirect bounce, use weights from earlier surface or volume bounce. */ @@ -275,8 +276,8 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, else { /* Direct light, use BSDFs at this bounce. */ shadow_flag |= PATH_RAY_SURFACE_PASS; - pass_diffuse_weight = packed_float3(bsdf_eval_pass_diffuse_weight(&bsdf_eval)); - pass_glossy_weight = packed_float3(bsdf_eval_pass_glossy_weight(&bsdf_eval)); + pass_diffuse_weight = PackedSpectrum(bsdf_eval_pass_diffuse_weight(&bsdf_eval)); + pass_glossy_weight = PackedSpectrum(bsdf_eval_pass_glossy_weight(&bsdf_eval)); } INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight; @@ -361,11 +362,10 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( float bsdf_pdf; BsdfEval bsdf_eval ccl_optional_struct_init; float3 bsdf_omega_in ccl_optional_struct_init; - differential3 bsdf_domega_in ccl_optional_struct_init; int label; label = shader_bsdf_sample_closure( - kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); + kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_pdf); if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) { return LABEL_NONE; @@ -384,12 +384,11 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( INTEGRATOR_STATE_WRITE(state, ray, tmax) = FLT_MAX; #ifdef __RAY_DIFFERENTIALS__ INTEGRATOR_STATE_WRITE(state, ray, dP) = differential_make_compact(sd->dP); - INTEGRATOR_STATE_WRITE(state, ray, dD) = differential_make_compact(bsdf_domega_in); #endif } /* Update throughput. */ - float3 throughput = INTEGRATOR_STATE(state, path, throughput); + Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); throughput *= bsdf_eval_sum(&bsdf_eval) / bsdf_pdf; INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput; @@ -461,7 +460,7 @@ ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg, path_state_rng_2D(kg, rng_state, PRNG_BSDF_U, &bsdf_u, &bsdf_v); float3 ao_N; - const float3 ao_weight = shader_bsdf_ao( + const Spectrum ao_weight = shader_bsdf_ao( kg, sd, kernel_data.integrator.ao_additive_factor, &ao_N); float3 ao_D; @@ -504,7 +503,8 @@ ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg, const uint16_t bounce = INTEGRATOR_STATE(state, path, bounce); const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce); uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag) | PATH_RAY_SHADOW_FOR_AO; - const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * shader_bsdf_alpha(kg, sd); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput) * + shader_bsdf_alpha(kg, sd); INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE( state, path, render_pixel_index); diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 4aab097a7d8..599454c5cb2 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -29,13 +29,13 @@ typedef enum VolumeIntegrateEvent { typedef struct VolumeIntegrateResult { /* Throughput and offset for direct light scattering. */ bool direct_scatter; - float3 direct_throughput; + Spectrum direct_throughput; float direct_t; ShaderVolumePhases direct_phases; /* Throughput and offset for indirect light scattering. */ bool indirect_scatter; - float3 indirect_throughput; + Spectrum indirect_throughput; float indirect_t; ShaderVolumePhases indirect_phases; } VolumeIntegrateResult; @@ -52,16 +52,16 @@ typedef struct VolumeIntegrateResult { * sigma_t = sigma_a + sigma_s */ typedef struct VolumeShaderCoefficients { - float3 sigma_t; - float3 sigma_s; - float3 emission; + Spectrum sigma_t; + Spectrum sigma_s; + Spectrum emission; } VolumeShaderCoefficients; /* Evaluate shader to get extinction coefficient at P. */ ccl_device_inline bool shadow_volume_shader_sample(KernelGlobals kg, IntegratorShadowState state, ccl_private ShaderData *ccl_restrict sd, - ccl_private float3 *ccl_restrict extinction) + ccl_private Spectrum *ccl_restrict extinction) { VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i)) shader_eval_volume<true>(kg, state, sd, PATH_RAY_SHADOW, volume_read_lambda_pass); @@ -89,9 +89,10 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals kg, return false; } - coeff->sigma_s = zero_float3(); - coeff->sigma_t = (sd->flag & SD_EXTINCTION) ? sd->closure_transparent_extinction : zero_float3(); - coeff->emission = (sd->flag & SD_EMISSION) ? sd->closure_emission_background : zero_float3(); + coeff->sigma_s = zero_spectrum(); + coeff->sigma_t = (sd->flag & SD_EXTINCTION) ? sd->closure_transparent_extinction : + zero_spectrum(); + coeff->emission = (sd->flag & SD_EMISSION) ? sd->closure_emission_background : zero_spectrum(); if (sd->flag & SD_SCATTER) { for (int i = 0; i < sd->num_closure; i++) { @@ -162,9 +163,9 @@ ccl_device_forceinline void volume_step_init(KernelGlobals kg, ccl_device void volume_shadow_homogeneous(KernelGlobals kg, IntegratorState state, ccl_private Ray *ccl_restrict ray, ccl_private ShaderData *ccl_restrict sd, - ccl_global float3 *ccl_restrict throughput) + ccl_global Spectrum *ccl_restrict throughput) { - float3 sigma_t = zero_float3(); + Spectrum sigma_t = zero_spectrum(); if (shadow_volume_shader_sample(kg, state, sd, &sigma_t)) { *throughput *= volume_color_transmittance(sigma_t, ray->tmax - ray->tmin); @@ -178,14 +179,14 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg, IntegratorShadowState state, ccl_private Ray *ccl_restrict ray, ccl_private ShaderData *ccl_restrict sd, - ccl_private float3 *ccl_restrict throughput, + ccl_private Spectrum *ccl_restrict throughput, const float object_step_size) { /* Load random number state. */ RNGState rng_state; shadow_path_state_rng_load(state, &rng_state); - float3 tp = *throughput; + Spectrum tp = *throughput; /* Prepare for stepping. * For shadows we do not offset all segments, since the starting point is @@ -207,7 +208,7 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg, /* compute extinction at the start */ float t = ray->tmin; - float3 sum = zero_float3(); + Spectrum sum = zero_spectrum(); for (int i = 0; i < max_steps; i++) { /* advance to new position */ @@ -215,7 +216,7 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg, float dt = new_t - t; float3 new_P = ray->P + ray->D * (t + dt * step_shade_offset); - float3 sigma_t = zero_float3(); + Spectrum sigma_t = zero_spectrum(); /* compute attenuation over segment */ sd->P = new_P; @@ -228,8 +229,7 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg, tp = *throughput * exp(sum); /* stop if nearly all light is blocked */ - if (tp.x < VOLUME_THROUGHPUT_EPSILON && tp.y < VOLUME_THROUGHPUT_EPSILON && - tp.z < VOLUME_THROUGHPUT_EPSILON) + if (reduce_max(tp) < VOLUME_THROUGHPUT_EPSILON) break; } } @@ -334,22 +334,22 @@ ccl_device float volume_equiangular_cdf(ccl_private const Ray *ccl_restrict ray, /* Distance sampling */ ccl_device float volume_distance_sample(float max_t, - float3 sigma_t, + Spectrum sigma_t, int channel, float xi, - ccl_private float3 *transmittance, - ccl_private float3 *pdf) + ccl_private Spectrum *transmittance, + ccl_private Spectrum *pdf) { /* xi is [0, 1[ so log(0) should never happen, division by zero is * avoided because sample_sigma_t > 0 when SD_SCATTER is set */ float sample_sigma_t = volume_channel_get(sigma_t, channel); - float3 full_transmittance = volume_color_transmittance(sigma_t, max_t); + Spectrum full_transmittance = volume_color_transmittance(sigma_t, max_t); float sample_transmittance = volume_channel_get(full_transmittance, channel); float sample_t = min(max_t, -logf(1.0f - xi * (1.0f - sample_transmittance)) / sample_sigma_t); *transmittance = volume_color_transmittance(sigma_t, sample_t); - *pdf = safe_divide_color(sigma_t * *transmittance, one_float3() - full_transmittance); + *pdf = safe_divide_color(sigma_t * *transmittance, one_spectrum() - full_transmittance); /* todo: optimization: when taken together with hit/miss decision, * the full_transmittance cancels out drops out and xi does not @@ -358,33 +358,36 @@ ccl_device float volume_distance_sample(float max_t, return sample_t; } -ccl_device float3 volume_distance_pdf(float max_t, float3 sigma_t, float sample_t) +ccl_device Spectrum volume_distance_pdf(float max_t, Spectrum sigma_t, float sample_t) { - float3 full_transmittance = volume_color_transmittance(sigma_t, max_t); - float3 transmittance = volume_color_transmittance(sigma_t, sample_t); + Spectrum full_transmittance = volume_color_transmittance(sigma_t, max_t); + Spectrum transmittance = volume_color_transmittance(sigma_t, sample_t); - return safe_divide_color(sigma_t * transmittance, one_float3() - full_transmittance); + return safe_divide_color(sigma_t * transmittance, one_spectrum() - full_transmittance); } /* Emission */ -ccl_device float3 volume_emission_integrate(ccl_private VolumeShaderCoefficients *coeff, - int closure_flag, - float3 transmittance, - float t) +ccl_device Spectrum volume_emission_integrate(ccl_private VolumeShaderCoefficients *coeff, + int closure_flag, + Spectrum transmittance, + float t) { /* integral E * exp(-sigma_t * t) from 0 to t = E * (1 - exp(-sigma_t * t))/sigma_t * this goes to E * t as sigma_t goes to zero * * todo: we should use an epsilon to avoid precision issues near zero sigma_t */ - float3 emission = coeff->emission; + Spectrum emission = coeff->emission; if (closure_flag & SD_EXTINCTION) { - float3 sigma_t = coeff->sigma_t; + Spectrum sigma_t = coeff->sigma_t; - emission.x *= (sigma_t.x > 0.0f) ? (1.0f - transmittance.x) / sigma_t.x : t; - emission.y *= (sigma_t.y > 0.0f) ? (1.0f - transmittance.y) / sigma_t.y : t; - emission.z *= (sigma_t.z > 0.0f) ? (1.0f - transmittance.z) / sigma_t.z : t; + FOREACH_SPECTRUM_CHANNEL (i) { + GET_SPECTRUM_CHANNEL(emission, i) *= (GET_SPECTRUM_CHANNEL(sigma_t, i) > 0.0f) ? + (1.0f - GET_SPECTRUM_CHANNEL(transmittance, i)) / + GET_SPECTRUM_CHANNEL(sigma_t, i) : + t; + } } else emission *= t; @@ -419,14 +422,14 @@ ccl_device_forceinline void volume_integrate_step_scattering( ccl_private const Ray *ray, const float3 equiangular_light_P, ccl_private const VolumeShaderCoefficients &ccl_restrict coeff, - const float3 transmittance, + const Spectrum transmittance, ccl_private VolumeIntegrateState &ccl_restrict vstate, ccl_private VolumeIntegrateResult &ccl_restrict result) { /* Pick random color channel, we use the Veach one-sample * model with balance heuristic for the channels. */ - const float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t); - float3 channel_pdf; + const Spectrum albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t); + Spectrum channel_pdf; const int channel = volume_sample_channel( albedo, result.indirect_throughput, vstate.rphase, &channel_pdf); @@ -435,7 +438,7 @@ ccl_device_forceinline void volume_integrate_step_scattering( if (result.direct_t >= vstate.tmin && result.direct_t <= vstate.tmax && vstate.equiangular_pdf > VOLUME_SAMPLE_PDF_CUTOFF) { const float new_dt = result.direct_t - vstate.tmin; - const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt); + const Spectrum new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt); result.direct_scatter = true; result.direct_throughput *= coeff.sigma_s * new_transmittance / vstate.equiangular_pdf; @@ -467,7 +470,7 @@ ccl_device_forceinline void volume_integrate_step_scattering( const float new_t = vstate.tmin + new_dt; /* transmittance and pdf */ - const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt); + const Spectrum new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt); const float distance_pdf = dot(channel_pdf, coeff.sigma_t * new_transmittance); if (vstate.distance_pdf * distance_pdf > VOLUME_SAMPLE_PDF_CUTOFF) { @@ -566,7 +569,7 @@ ccl_device_forceinline void volume_integrate_heterogeneous( vstate.distance_pdf = 1.0f; /* Initialize volume integration result. */ - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); result.direct_throughput = throughput; result.indirect_throughput = throughput; @@ -579,9 +582,9 @@ ccl_device_forceinline void volume_integrate_heterogeneous( # ifdef __DENOISING_FEATURES__ const bool write_denoising_features = (INTEGRATOR_STATE(state, path, flag) & PATH_RAY_DENOISING_FEATURES); - float3 accum_albedo = zero_float3(); + Spectrum accum_albedo = zero_spectrum(); # endif - float3 accum_emission = zero_float3(); + Spectrum accum_emission = zero_spectrum(); for (int i = 0; i < max_steps; i++) { /* Advance to new position */ @@ -596,16 +599,16 @@ ccl_device_forceinline void volume_integrate_heterogeneous( /* Evaluate transmittance over segment. */ const float dt = (vstate.tmax - vstate.tmin); - const float3 transmittance = (closure_flag & SD_EXTINCTION) ? - volume_color_transmittance(coeff.sigma_t, dt) : - one_float3(); + const Spectrum transmittance = (closure_flag & SD_EXTINCTION) ? + volume_color_transmittance(coeff.sigma_t, dt) : + one_spectrum(); /* Emission. */ if (closure_flag & SD_EMISSION) { /* Only write emission before indirect light scatter position, since we terminate * stepping at that point if we have already found a direct light scatter position. */ if (!result.indirect_scatter) { - const float3 emission = volume_emission_integrate( + const Spectrum emission = volume_emission_integrate( &coeff, closure_flag, transmittance, dt); accum_emission += result.indirect_throughput * emission; } @@ -616,8 +619,8 @@ ccl_device_forceinline void volume_integrate_heterogeneous( # ifdef __DENOISING_FEATURES__ /* Accumulate albedo for denoising features. */ if (write_denoising_features && (closure_flag & SD_SCATTER)) { - const float3 albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t); - accum_albedo += result.indirect_throughput * albedo * (one_float3() - transmittance); + const Spectrum albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t); + accum_albedo += result.indirect_throughput * albedo * (one_spectrum() - transmittance); } # endif @@ -634,7 +637,7 @@ ccl_device_forceinline void volume_integrate_heterogeneous( /* Stop if nearly all light blocked. */ if (!result.indirect_scatter) { if (reduce_max(result.indirect_throughput) < VOLUME_THROUGHPUT_EPSILON) { - result.indirect_throughput = zero_float3(); + result.indirect_throughput = zero_spectrum(); break; } } @@ -715,7 +718,7 @@ ccl_device_forceinline void integrate_volume_direct_light( ccl_private const RNGState *ccl_restrict rng_state, const float3 P, ccl_private const ShaderVolumePhases *ccl_restrict phases, - ccl_private const float3 throughput, + ccl_private const Spectrum throughput, ccl_private LightSample *ccl_restrict ls) { PROFILING_INIT(kg, PROFILING_SHADE_VOLUME_DIRECT_LIGHT); @@ -753,7 +756,7 @@ ccl_device_forceinline void integrate_volume_direct_light( * non-constant light sources. */ ShaderDataTinyStorage emission_sd_storage; ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage); - const float3 light_eval = light_sample_shader_eval(kg, state, emission_sd, ls, sd->time); + const Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, ls, sd->time); if (is_zero(light_eval)) { return; } @@ -796,11 +799,11 @@ ccl_device_forceinline void integrate_volume_direct_light( const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce); uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag); shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0; - const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval); + const Spectrum throughput_phase = throughput * bsdf_eval_sum(&phase_eval); if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { - packed_float3 pass_diffuse_weight; - packed_float3 pass_glossy_weight; + PackedSpectrum pass_diffuse_weight; + PackedSpectrum pass_glossy_weight; if (shadow_flag & PATH_RAY_ANY_PASS) { /* Indirect bounce, use weights from earlier surface or volume bounce. */ @@ -810,8 +813,8 @@ ccl_device_forceinline void integrate_volume_direct_light( else { /* Direct light, no diffuse/glossy distinction needed for volumes. */ shadow_flag |= PATH_RAY_VOLUME_PASS; - pass_diffuse_weight = packed_float3(one_float3()); - pass_glossy_weight = packed_float3(zero_float3()); + pass_diffuse_weight = one_spectrum(); + pass_glossy_weight = zero_spectrum(); } INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight; @@ -868,17 +871,9 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( float phase_pdf; BsdfEval phase_eval ccl_optional_struct_init; float3 phase_omega_in ccl_optional_struct_init; - differential3 phase_domega_in ccl_optional_struct_init; - - const int label = shader_volume_phase_sample(kg, - sd, - phases, - phase_u, - phase_v, - &phase_eval, - &phase_omega_in, - &phase_domega_in, - &phase_pdf); + + const int label = shader_volume_phase_sample( + kg, sd, phases, phase_u, phase_v, &phase_eval, &phase_omega_in, &phase_pdf); if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval)) { return false; @@ -891,20 +886,19 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( INTEGRATOR_STATE_WRITE(state, ray, tmax) = FLT_MAX; # ifdef __RAY_DIFFERENTIALS__ INTEGRATOR_STATE_WRITE(state, ray, dP) = differential_make_compact(sd->dP); - INTEGRATOR_STATE_WRITE(state, ray, dD) = differential_make_compact(phase_domega_in); # endif // Save memory by storing last hit prim and object in isect INTEGRATOR_STATE_WRITE(state, isect, prim) = sd->prim; INTEGRATOR_STATE_WRITE(state, isect, object) = sd->object; /* Update throughput. */ - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); - const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval) / phase_pdf; + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum throughput_phase = throughput * bsdf_eval_sum(&phase_eval) / phase_pdf; INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput_phase; if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { - INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_float3(); - INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_float3(); + INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_spectrum(); + INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_spectrum(); } /* Update path state */ diff --git a/intern/cycles/kernel/integrator/shader_eval.h b/intern/cycles/kernel/integrator/shader_eval.h index ed4d973e864..e6b0d0a6466 100644 --- a/intern/cycles/kernel/integrator/shader_eval.h +++ b/intern/cycles/kernel/integrator/shader_eval.h @@ -98,7 +98,7 @@ ccl_device_inline void shader_prepare_surface_closures(KernelGlobals kg, /* Filter out closures. */ if (kernel_data.integrator.filter_closures) { if (kernel_data.integrator.filter_closures & FILTER_CLOSURE_EMISSION) { - sd->closure_emission_background = zero_float3(); + sd->closure_emission_background = zero_spectrum(); } if (kernel_data.integrator.filter_closures & FILTER_CLOSURE_DIRECT_LIGHT) { @@ -231,7 +231,7 @@ ccl_device_inline float _shader_bsdf_multi_eval(KernelGlobals kg, if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { if (CLOSURE_IS_BSDF(sc->type) && !_shader_bsdf_exclude(sc->type, light_shader_flags)) { float bsdf_pdf = 0.0f; - float3 eval = bsdf_eval(kg, sd, sc, omega_in, is_transmission, &bsdf_pdf); + Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, is_transmission, &bsdf_pdf); if (bsdf_pdf != 0.0f) { bsdf_eval_accum(result_eval, sc->type, eval * sc->weight); @@ -259,7 +259,7 @@ ccl_device_inline ccl_private BsdfEval *bsdf_eval, const uint light_shader_flags) { - bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_float3()); + bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_spectrum()); return _shader_bsdf_multi_eval( kg, sd, omega_in, is_transmission, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags); @@ -309,11 +309,11 @@ ccl_device_inline ccl_private const ShaderClosure *shader_bsdf_bssrdf_pick( } /* Return weight for picked BSSRDF. */ -ccl_device_inline float3 +ccl_device_inline Spectrum shader_bssrdf_sample_weight(ccl_private const ShaderData *ccl_restrict sd, ccl_private const ShaderClosure *ccl_restrict bssrdf_sc) { - float3 weight = bssrdf_sc->weight; + Spectrum weight = bssrdf_sc->weight; if (sd->num_closure > 1) { float sum = 0.0f; @@ -339,17 +339,16 @@ ccl_device int shader_bsdf_sample_closure(KernelGlobals kg, float randv, ccl_private BsdfEval *bsdf_eval, ccl_private float3 *omega_in, - ccl_private differential3 *domega_in, ccl_private float *pdf) { /* BSSRDF should already have been handled elsewhere. */ kernel_assert(CLOSURE_IS_BSDF(sc->type)); int label; - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); *pdf = 0.0f; - label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); + label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, pdf); if (*pdf != 0.0f) { bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight); @@ -385,16 +384,16 @@ ccl_device float shader_bsdf_average_roughness(ccl_private const ShaderData *sd) return (sum_weight > 0.0f) ? roughness / sum_weight : 0.0f; } -ccl_device float3 shader_bsdf_transparency(KernelGlobals kg, ccl_private const ShaderData *sd) +ccl_device Spectrum shader_bsdf_transparency(KernelGlobals kg, ccl_private const ShaderData *sd) { if (sd->flag & SD_HAS_ONLY_VOLUME) { - return one_float3(); + return one_spectrum(); } else if (sd->flag & SD_TRANSPARENT) { return sd->closure_transparent_extinction; } else { - return zero_float3(); + return zero_spectrum(); } } @@ -406,7 +405,7 @@ ccl_device void shader_bsdf_disable_transparency(KernelGlobals kg, ccl_private S if (sc->type == CLOSURE_BSDF_TRANSPARENT_ID) { sc->sample_weight = 0.0f; - sc->weight = zero_float3(); + sc->weight = zero_spectrum(); } } @@ -414,19 +413,18 @@ ccl_device void shader_bsdf_disable_transparency(KernelGlobals kg, ccl_private S } } -ccl_device float3 shader_bsdf_alpha(KernelGlobals kg, ccl_private const ShaderData *sd) +ccl_device Spectrum shader_bsdf_alpha(KernelGlobals kg, ccl_private const ShaderData *sd) { - float3 alpha = one_float3() - shader_bsdf_transparency(kg, sd); + Spectrum alpha = one_spectrum() - shader_bsdf_transparency(kg, sd); - alpha = max(alpha, zero_float3()); - alpha = min(alpha, one_float3()); + alpha = saturate(alpha); return alpha; } -ccl_device float3 shader_bsdf_diffuse(KernelGlobals kg, ccl_private const ShaderData *sd) +ccl_device Spectrum shader_bsdf_diffuse(KernelGlobals kg, ccl_private const ShaderData *sd) { - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); for (int i = 0; i < sd->num_closure; i++) { ccl_private const ShaderClosure *sc = &sd->closure[i]; @@ -438,9 +436,9 @@ ccl_device float3 shader_bsdf_diffuse(KernelGlobals kg, ccl_private const Shader return eval; } -ccl_device float3 shader_bsdf_glossy(KernelGlobals kg, ccl_private const ShaderData *sd) +ccl_device Spectrum shader_bsdf_glossy(KernelGlobals kg, ccl_private const ShaderData *sd) { - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); for (int i = 0; i < sd->num_closure; i++) { ccl_private const ShaderClosure *sc = &sd->closure[i]; @@ -452,9 +450,9 @@ ccl_device float3 shader_bsdf_glossy(KernelGlobals kg, ccl_private const ShaderD return eval; } -ccl_device float3 shader_bsdf_transmission(KernelGlobals kg, ccl_private const ShaderData *sd) +ccl_device Spectrum shader_bsdf_transmission(KernelGlobals kg, ccl_private const ShaderData *sd) { - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); for (int i = 0; i < sd->num_closure; i++) { ccl_private const ShaderClosure *sc = &sd->closure[i]; @@ -479,12 +477,12 @@ ccl_device float3 shader_bsdf_average_normal(KernelGlobals kg, ccl_private const return (is_zero(N)) ? sd->N : normalize(N); } -ccl_device float3 shader_bsdf_ao(KernelGlobals kg, - ccl_private const ShaderData *sd, - const float ao_factor, - ccl_private float3 *N_) +ccl_device Spectrum shader_bsdf_ao(KernelGlobals kg, + ccl_private const ShaderData *sd, + const float ao_factor, + ccl_private float3 *N_) { - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); float3 N = zero_float3(); for (int i = 0; i < sd->num_closure; i++) { @@ -525,15 +523,17 @@ ccl_device float3 shader_bssrdf_normal(ccl_private const ShaderData *sd) ccl_device bool shader_constant_emission_eval(KernelGlobals kg, int shader, - ccl_private float3 *eval) + ccl_private Spectrum *eval) { int shader_index = shader & SHADER_MASK; int shader_flag = kernel_data_fetch(shaders, shader_index).flags; if (shader_flag & SD_HAS_CONSTANT_EMISSION) { - *eval = make_float3(kernel_data_fetch(shaders, shader_index).constant_emission[0], - kernel_data_fetch(shaders, shader_index).constant_emission[1], - kernel_data_fetch(shaders, shader_index).constant_emission[2]); + const float3 emission_rgb = make_float3( + kernel_data_fetch(shaders, shader_index).constant_emission[0], + kernel_data_fetch(shaders, shader_index).constant_emission[1], + kernel_data_fetch(shaders, shader_index).constant_emission[2]); + *eval = rgb_to_spectrum(emission_rgb); return true; } @@ -543,39 +543,39 @@ ccl_device bool shader_constant_emission_eval(KernelGlobals kg, /* Background */ -ccl_device float3 shader_background_eval(ccl_private const ShaderData *sd) +ccl_device Spectrum shader_background_eval(ccl_private const ShaderData *sd) { if (sd->flag & SD_EMISSION) { return sd->closure_emission_background; } else { - return zero_float3(); + return zero_spectrum(); } } /* Emission */ -ccl_device float3 shader_emissive_eval(ccl_private const ShaderData *sd) +ccl_device Spectrum shader_emissive_eval(ccl_private const ShaderData *sd) { if (sd->flag & SD_EMISSION) { return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background; } else { - return zero_float3(); + return zero_spectrum(); } } /* Holdout */ -ccl_device float3 shader_holdout_apply(KernelGlobals kg, ccl_private ShaderData *sd) +ccl_device Spectrum shader_holdout_apply(KernelGlobals kg, ccl_private ShaderData *sd) { - float3 weight = zero_float3(); + Spectrum weight = zero_spectrum(); /* For objects marked as holdout, preserve transparency and remove all other * closures, replacing them with a holdout weight. */ if (sd->object_flag & SD_OBJECT_HOLDOUT_MASK) { if ((sd->flag & SD_TRANSPARENT) && !(sd->flag & SD_HAS_ONLY_VOLUME)) { - weight = one_float3() - sd->closure_transparent_extinction; + weight = one_spectrum() - sd->closure_transparent_extinction; for (int i = 0; i < sd->num_closure; i++) { ccl_private ShaderClosure *sc = &sd->closure[i]; @@ -587,7 +587,7 @@ ccl_device float3 shader_holdout_apply(KernelGlobals kg, ccl_private ShaderData sd->flag &= ~(SD_CLOSURE_FLAGS - (SD_TRANSPARENT | SD_BSDF)); } else { - weight = one_float3(); + weight = one_spectrum(); } } else { @@ -642,12 +642,12 @@ ccl_device void shader_eval_surface(KernelGlobals kg, svm_eval_nodes<node_feature_mask, SHADER_TYPE_SURFACE>(kg, state, sd, buffer, path_flag); #else if (sd->object == OBJECT_NONE) { - sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f); + sd->closure_emission_background = make_spectrum(0.8f); sd->flag |= SD_EMISSION; } else { ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc( - sd, sizeof(DiffuseBsdf), make_float3(0.8f, 0.8f, 0.8f)); + sd, sizeof(DiffuseBsdf), make_spectrum(0.8f)); if (bsdf != NULL) { bsdf->N = sd->N; sd->flag |= bsdf_diffuse_setup(bsdf); @@ -676,7 +676,7 @@ ccl_device_inline float _shader_volume_phase_multi_eval( ccl_private const ShaderVolumeClosure *svc = &phases->closure[i]; float phase_pdf = 0.0f; - float3 eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf); + Spectrum eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf); if (phase_pdf != 0.0f) { bsdf_eval_accum(result_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); @@ -695,7 +695,7 @@ ccl_device float shader_volume_phase_eval(KernelGlobals kg, const float3 omega_in, ccl_private BsdfEval *phase_eval) { - bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_float3()); + bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_spectrum()); return _shader_volume_phase_multi_eval(sd, phases, omega_in, -1, phase_eval, 0.0f, 0.0f); } @@ -707,7 +707,6 @@ ccl_device int shader_volume_phase_sample(KernelGlobals kg, float randv, ccl_private BsdfEval *phase_eval, ccl_private float3 *omega_in, - ccl_private differential3 *domega_in, ccl_private float *pdf) { int sampled = 0; @@ -747,10 +746,10 @@ ccl_device int shader_volume_phase_sample(KernelGlobals kg, * depending on color channels, even if this is perhaps not a common case */ ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled]; int label; - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); *pdf = 0.0f; - label = volume_phase_sample(sd, svc, randu, randv, &eval, omega_in, domega_in, pdf); + label = volume_phase_sample(sd, svc, randu, randv, &eval, omega_in, pdf); if (*pdf != 0.0f) { bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); @@ -766,14 +765,13 @@ ccl_device int shader_phase_sample_closure(KernelGlobals kg, float randv, ccl_private BsdfEval *phase_eval, ccl_private float3 *omega_in, - ccl_private differential3 *domega_in, ccl_private float *pdf) { int label; - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); *pdf = 0.0f; - label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf); + label = volume_phase_sample(sd, sc, randu, randv, &eval, omega_in, pdf); if (*pdf != 0.0f) bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); diff --git a/intern/cycles/kernel/integrator/shadow_catcher.h b/intern/cycles/kernel/integrator/shadow_catcher.h index ff63625aceb..7103b6032ac 100644 --- a/intern/cycles/kernel/integrator/shadow_catcher.h +++ b/intern/cycles/kernel/integrator/shadow_catcher.h @@ -93,7 +93,7 @@ ccl_device_forceinline void kernel_write_shadow_catcher_bounce_data( /* Since the split is done, the sample does not contribute to the matte, so accumulate it as * transparency to the matte. */ - const float3 throughput = INTEGRATOR_STATE(state, path, throughput); + const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); kernel_write_pass_float(buffer + kernel_data.film.pass_shadow_catcher_matte + 3, average(throughput)); } diff --git a/intern/cycles/kernel/integrator/shadow_state_template.h b/intern/cycles/kernel/integrator/shadow_state_template.h index c340467606d..3b490ecffdd 100644 --- a/intern/cycles/kernel/integrator/shadow_state_template.h +++ b/intern/cycles/kernel/integrator/shadow_state_template.h @@ -27,15 +27,15 @@ KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, queued_kernel, KERNEL_FEATURE_PATH_T /* enum PathRayFlag */ KERNEL_STRUCT_MEMBER(shadow_path, uint32_t, flag, KERNEL_FEATURE_PATH_TRACING) /* Throughput. */ -KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, throughput, KERNEL_FEATURE_PATH_TRACING) +KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, throughput, KERNEL_FEATURE_PATH_TRACING) /* Throughput for shadow pass. */ KERNEL_STRUCT_MEMBER(shadow_path, - packed_float3, + PackedSpectrum, unshadowed_throughput, KERNEL_FEATURE_SHADOW_PASS | KERNEL_FEATURE_AO_ADDITIVE) /* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */ -KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES) -KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES) +KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES) +KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES) /* Number of intersections found by ray-tracing. */ KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, num_hits, KERNEL_FEATURE_PATH_TRACING) /* Light group. */ diff --git a/intern/cycles/kernel/integrator/state_template.h b/intern/cycles/kernel/integrator/state_template.h index 5c2af131945..f4e280e4cb2 100644 --- a/intern/cycles/kernel/integrator/state_template.h +++ b/intern/cycles/kernel/integrator/state_template.h @@ -46,12 +46,12 @@ KERNEL_STRUCT_MEMBER(path, float, min_ray_pdf, KERNEL_FEATURE_PATH_TRACING) /* Continuation probability for path termination. */ KERNEL_STRUCT_MEMBER(path, float, continuation_probability, KERNEL_FEATURE_PATH_TRACING) /* Throughput. */ -KERNEL_STRUCT_MEMBER(path, packed_float3, throughput, KERNEL_FEATURE_PATH_TRACING) +KERNEL_STRUCT_MEMBER(path, PackedSpectrum, throughput, KERNEL_FEATURE_PATH_TRACING) /* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */ -KERNEL_STRUCT_MEMBER(path, packed_float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES) -KERNEL_STRUCT_MEMBER(path, packed_float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES) +KERNEL_STRUCT_MEMBER(path, PackedSpectrum, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES) +KERNEL_STRUCT_MEMBER(path, PackedSpectrum, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES) /* Denoising. */ -KERNEL_STRUCT_MEMBER(path, packed_float3, denoising_feature_throughput, KERNEL_FEATURE_DENOISING) +KERNEL_STRUCT_MEMBER(path, PackedSpectrum, denoising_feature_throughput, KERNEL_FEATURE_DENOISING) /* Shader sorting. */ /* TODO: compress as uint16? or leave out entirely and recompute key in sorting code? */ KERNEL_STRUCT_MEMBER(path, uint32_t, shader_sort_key, KERNEL_FEATURE_PATH_TRACING) @@ -84,8 +84,8 @@ KERNEL_STRUCT_END(isect) /*************** Subsurface closure state for subsurface kernel ***************/ KERNEL_STRUCT_BEGIN(subsurface) -KERNEL_STRUCT_MEMBER(subsurface, packed_float3, albedo, KERNEL_FEATURE_SUBSURFACE) -KERNEL_STRUCT_MEMBER(subsurface, packed_float3, radius, KERNEL_FEATURE_SUBSURFACE) +KERNEL_STRUCT_MEMBER(subsurface, PackedSpectrum, albedo, KERNEL_FEATURE_SUBSURFACE) +KERNEL_STRUCT_MEMBER(subsurface, PackedSpectrum, radius, KERNEL_FEATURE_SUBSURFACE) KERNEL_STRUCT_MEMBER(subsurface, float, anisotropy, KERNEL_FEATURE_SUBSURFACE) KERNEL_STRUCT_MEMBER(subsurface, packed_float3, Ng, KERNEL_FEATURE_SUBSURFACE) KERNEL_STRUCT_END(subsurface) diff --git a/intern/cycles/kernel/integrator/subsurface.h b/intern/cycles/kernel/integrator/subsurface.h index 2f96f215d8a..ee3a619f968 100644 --- a/intern/cycles/kernel/integrator/subsurface.h +++ b/intern/cycles/kernel/integrator/subsurface.h @@ -51,7 +51,7 @@ ccl_device int subsurface_bounce(KernelGlobals kg, PATH_RAY_SUBSURFACE_RANDOM_WALK); /* Compute weight, optionally including Fresnel from entry point. */ - float3 weight = shader_bssrdf_sample_weight(sd, sc); + Spectrum weight = shader_bssrdf_sample_weight(sd, sc); # ifdef __PRINCIPLED__ if (bssrdf->roughness != FLT_MAX) { path_flag |= PATH_RAY_SUBSURFACE_USE_FRESNEL; @@ -70,8 +70,8 @@ ccl_device int subsurface_bounce(KernelGlobals kg, if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { if (INTEGRATOR_STATE(state, path, bounce) == 0) { - INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_float3(); - INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_float3(); + INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_spectrum(); + INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_spectrum(); } } @@ -99,7 +99,7 @@ ccl_device void subsurface_shader_data_setup(KernelGlobals kg, sd->num_closure = 0; sd->num_closure_left = kernel_data.max_closures; - const float3 weight = one_float3(); + const Spectrum weight = one_spectrum(); # ifdef __PRINCIPLED__ if (path_flag & PATH_RAY_SUBSURFACE_USE_FRESNEL) { diff --git a/intern/cycles/kernel/integrator/subsurface_disk.h b/intern/cycles/kernel/integrator/subsurface_disk.h index 60b63c075a0..77763f702d8 100644 --- a/intern/cycles/kernel/integrator/subsurface_disk.h +++ b/intern/cycles/kernel/integrator/subsurface_disk.h @@ -9,11 +9,11 @@ CCL_NAMESPACE_BEGIN * http://library.imageworks.com/pdfs/imageworks-library-BSSRDF-sampling.pdf */ -ccl_device_inline float3 subsurface_disk_eval(const float3 radius, float disk_r, float r) +ccl_device_inline Spectrum subsurface_disk_eval(const Spectrum radius, float disk_r, float r) { - const float3 eval = bssrdf_eval(radius, r); + const Spectrum eval = bssrdf_eval(radius, r); const float pdf = bssrdf_pdf(radius, disk_r); - return (pdf > 0.0f) ? eval / pdf : zero_float3(); + return (pdf > 0.0f) ? eval / pdf : zero_spectrum(); } /* Subsurface scattering step, from a point on the surface to other @@ -37,7 +37,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg, const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); /* Read subsurface scattering parameters. */ - const float3 radius = INTEGRATOR_STATE(state, subsurface, radius); + const Spectrum radius = INTEGRATOR_STATE(state, subsurface, radius); /* Pick random axis in local frame and point on disk. */ float3 disk_N, disk_T, disk_B; @@ -108,7 +108,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg, * traversal algorithm. */ sort_intersections_and_normals(ss_isect.hits, ss_isect.Ng, num_eval_hits); - float3 weights[BSSRDF_MAX_HITS]; /* TODO: zero? */ + Spectrum weights[BSSRDF_MAX_HITS]; /* TODO: zero? */ float sum_weights = 0.0f; for (int hit = 0; hit < num_eval_hits; hit++) { @@ -150,7 +150,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg, const float r = len(hit_P - P); /* Evaluate profiles. */ - const float3 weight = subsurface_disk_eval(radius, disk_r, r) * w; + const Spectrum weight = subsurface_disk_eval(radius, disk_r, r) * w; /* Store result. */ ss_isect.Ng[hit] = hit_Ng; @@ -167,7 +167,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg, float partial_sum = 0.0f; for (int hit = 0; hit < num_eval_hits; hit++) { - const float3 weight = weights[hit]; + const Spectrum weight = weights[hit]; const float sample_weight = average(fabs(weight)); float next_sum = partial_sum + sample_weight; diff --git a/intern/cycles/kernel/integrator/subsurface_random_walk.h b/intern/cycles/kernel/integrator/subsurface_random_walk.h index e43bbb3c50a..baca0d745e8 100644 --- a/intern/cycles/kernel/integrator/subsurface_random_walk.h +++ b/intern/cycles/kernel/integrator/subsurface_random_walk.h @@ -65,19 +65,20 @@ ccl_device void subsurface_random_walk_remap(const float albedo, *sigma_t = sigma_t_prime / (1.0f - g); } -ccl_device void subsurface_random_walk_coefficients(const float3 albedo, - const float3 radius, +ccl_device void subsurface_random_walk_coefficients(const Spectrum albedo, + const Spectrum radius, const float anisotropy, - ccl_private float3 *sigma_t, - ccl_private float3 *alpha, - ccl_private float3 *throughput) + ccl_private Spectrum *sigma_t, + ccl_private Spectrum *alpha, + ccl_private Spectrum *throughput) { - float sigma_t_x, sigma_t_y, sigma_t_z; - float alpha_x, alpha_y, alpha_z; - - subsurface_random_walk_remap(albedo.x, radius.x, anisotropy, &sigma_t_x, &alpha_x); - subsurface_random_walk_remap(albedo.y, radius.y, anisotropy, &sigma_t_y, &alpha_y); - subsurface_random_walk_remap(albedo.z, radius.z, anisotropy, &sigma_t_z, &alpha_z); + FOREACH_SPECTRUM_CHANNEL (i) { + subsurface_random_walk_remap(GET_SPECTRUM_CHANNEL(albedo, i), + GET_SPECTRUM_CHANNEL(radius, i), + anisotropy, + &GET_SPECTRUM_CHANNEL(*sigma_t, i), + &GET_SPECTRUM_CHANNEL(*alpha, i)); + } /* Throughput already contains closure weight at this point, which includes the * albedo, as well as closure mixing and Fresnel weights. Divide out the albedo @@ -88,21 +89,12 @@ ccl_device void subsurface_random_walk_coefficients(const float3 albedo, * infinite phase functions. To avoid a sharp discontinuity as we go from * such values to 0.0, increase alpha and reduce the throughput to compensate. */ const float min_alpha = 0.2f; - if (alpha_x < min_alpha) { - (*throughput).x *= alpha_x / min_alpha; - alpha_x = min_alpha; - } - if (alpha_y < min_alpha) { - (*throughput).y *= alpha_y / min_alpha; - alpha_y = min_alpha; - } - if (alpha_z < min_alpha) { - (*throughput).z *= alpha_z / min_alpha; - alpha_z = min_alpha; + FOREACH_SPECTRUM_CHANNEL (i) { + if (GET_SPECTRUM_CHANNEL(*alpha, i) < min_alpha) { + GET_SPECTRUM_CHANNEL(*throughput, i) *= GET_SPECTRUM_CHANNEL(*alpha, i) / min_alpha; + GET_SPECTRUM_CHANNEL(*alpha, i) = min_alpha; + } } - - *sigma_t = make_float3(sigma_t_x, sigma_t_y, sigma_t_z); - *alpha = make_float3(alpha_x, alpha_y, alpha_z); } /* References for Dwivedi sampling: @@ -151,12 +143,12 @@ ccl_device_forceinline float3 direction_from_cosine(float3 D, float cos_theta, f return dir.x * T + dir.y * B + dir.z * D; } -ccl_device_forceinline float3 subsurface_random_walk_pdf(float3 sigma_t, - float t, - bool hit, - ccl_private float3 *transmittance) +ccl_device_forceinline Spectrum subsurface_random_walk_pdf(Spectrum sigma_t, + float t, + bool hit, + ccl_private Spectrum *transmittance) { - float3 T = volume_color_transmittance(sigma_t, t); + Spectrum T = volume_color_transmittance(sigma_t, t); if (transmittance) { *transmittance = T; } @@ -207,14 +199,14 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, /* Convert subsurface to volume coefficients. * The single-scattering albedo is named alpha to avoid confusion with the surface albedo. */ - const float3 albedo = INTEGRATOR_STATE(state, subsurface, albedo); - const float3 radius = INTEGRATOR_STATE(state, subsurface, radius); + const Spectrum albedo = INTEGRATOR_STATE(state, subsurface, albedo); + const Spectrum radius = INTEGRATOR_STATE(state, subsurface, radius); const float anisotropy = INTEGRATOR_STATE(state, subsurface, anisotropy); - float3 sigma_t, alpha; - float3 throughput = INTEGRATOR_STATE_WRITE(state, path, throughput); + Spectrum sigma_t, alpha; + Spectrum throughput = INTEGRATOR_STATE_WRITE(state, path, throughput); subsurface_random_walk_coefficients(albedo, radius, anisotropy, &sigma_t, &alpha, &throughput); - float3 sigma_s = sigma_t * alpha; + Spectrum sigma_s = sigma_t * alpha; /* Theoretically it should be better to use the exact alpha for the channel we're sampling at * each bounce, but in practice there doesn't seem to be a noticeable difference in exchange @@ -237,7 +229,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, const float phase_log = logf((diffusion_length + 1.0f) / (diffusion_length - 1.0f)); /* Modify state for RNGs, decorrelated from other paths. */ - rng_state.rng_hash = cmj_hash(rng_state.rng_hash + rng_state.rng_offset, 0xdeadbeef); + rng_state.rng_hash = hash_cmj_seeded_uint(rng_state.rng_hash + rng_state.rng_offset, 0xdeadbeef); /* Random walk until we hit the surface again. */ bool hit = false; @@ -249,10 +241,10 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, const float guided_fraction = 1.0f - fmaxf(0.5f, powf(fabsf(anisotropy), 0.125f)); #ifdef SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL - float3 sigma_s_star = sigma_s * (1.0f - anisotropy); - float3 sigma_t_star = sigma_t - sigma_s + sigma_s_star; - float3 sigma_t_org = sigma_t; - float3 sigma_s_org = sigma_s; + Spectrum sigma_s_star = sigma_s * (1.0f - anisotropy); + Spectrum sigma_t_star = sigma_t - sigma_s + sigma_s_star; + Spectrum sigma_t_org = sigma_t; + Spectrum sigma_s_org = sigma_s; const float anisotropy_org = anisotropy; const float guided_fraction_org = guided_fraction; #endif @@ -264,7 +256,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, #ifdef SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL // shadow with local variables according to depth float anisotropy, guided_fraction; - float3 sigma_s, sigma_t; + Spectrum sigma_s, sigma_t; if (bounce <= SUBSURFACE_RANDOM_WALK_SIMILARITY_LEVEL) { anisotropy = anisotropy_org; guided_fraction = guided_fraction_org; @@ -281,7 +273,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, /* Sample color channel, use MIS with balance heuristic. */ float rphase = path_state_rng_1D(kg, &rng_state, PRNG_PHASE_CHANNEL); - float3 channel_pdf; + Spectrum channel_pdf; int channel = volume_sample_channel(alpha, throughput, rphase, &channel_pdf); float sample_sigma_t = volume_channel_get(sigma_t, channel); float randt = path_state_rng_1D(kg, &rng_state, PRNG_SCATTER_DISTANCE); @@ -399,16 +391,17 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, /* Advance to new scatter location. */ ray.P += t * ray.D; - float3 transmittance; - float3 pdf = subsurface_random_walk_pdf(sigma_t, t, hit, &transmittance); + Spectrum transmittance; + Spectrum pdf = subsurface_random_walk_pdf(sigma_t, t, hit, &transmittance); if (bounce > 0) { /* Compute PDF just like we do for classic sampling, but with the stretched sigma_t. */ - float3 guided_pdf = subsurface_random_walk_pdf(forward_stretching * sigma_t, t, hit, NULL); + Spectrum guided_pdf = subsurface_random_walk_pdf(forward_stretching * sigma_t, t, hit, NULL); if (have_opposite_interface) { /* First step of MIS: Depending on geometry we might have two methods for guided * sampling, so perform MIS between them. */ - float3 back_pdf = subsurface_random_walk_pdf(backward_stretching * sigma_t, t, hit, NULL); + Spectrum back_pdf = subsurface_random_walk_pdf( + backward_stretching * sigma_t, t, hit, NULL); guided_pdf = mix( guided_pdf * forward_pdf_factor, back_pdf * backward_pdf_factor, backward_fraction); } @@ -430,9 +423,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, /* If we hit the surface, we are done. */ break; } - else if (throughput.x < VOLUME_THROUGHPUT_EPSILON && - throughput.y < VOLUME_THROUGHPUT_EPSILON && - throughput.z < VOLUME_THROUGHPUT_EPSILON) { + else if (reduce_max(throughput) < VOLUME_THROUGHPUT_EPSILON) { /* Avoid unnecessary work and precision issue when throughput gets really small. */ break; } diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h index 2e309cee43f..4195675dd13 100644 --- a/intern/cycles/kernel/light/sample.h +++ b/intern/cycles/kernel/light/sample.h @@ -14,7 +14,7 @@ CCL_NAMESPACE_BEGIN /* Evaluate shader on light. */ -ccl_device_noinline_cpu float3 +ccl_device_noinline_cpu Spectrum light_sample_shader_eval(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *ccl_restrict emission_sd, @@ -22,7 +22,7 @@ light_sample_shader_eval(KernelGlobals kg, float time) { /* setup shading at emitter */ - float3 eval = zero_float3(); + Spectrum eval = zero_spectrum(); if (shader_constant_emission_eval(kg, ls->shader, &eval)) { if ((ls->prim != PRIM_NONE) && dot(ls->Ng, ls->D) > 0.0f) { @@ -82,7 +82,8 @@ light_sample_shader_eval(KernelGlobals kg, if (ls->lamp != LAMP_NONE) { ccl_global const KernelLight *klight = &kernel_data_fetch(lights, ls->lamp); - eval *= make_float3(klight->strength[0], klight->strength[1], klight->strength[2]); + eval *= rgb_to_spectrum( + make_float3(klight->strength[0], klight->strength[1], klight->strength[2])); } return eval; diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index 865ff4ddc6d..4b5a2686117 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -14,8 +14,12 @@ // clang-format off #include "kernel/device/cpu/compat.h" +#include "kernel/device/cpu/globals.h" + #include "kernel/closure/alloc.h" #include "kernel/closure/emissive.h" + +#include "kernel/util/color.h" // clang-format on CCL_NAMESPACE_BEGIN @@ -32,7 +36,7 @@ class GenericBackgroundClosure : public CClosurePrimitive { public: void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) { - background_setup(sd, weight); + background_setup(sd, rgb_to_spectrum(weight)); } }; @@ -47,7 +51,7 @@ class HoldoutClosure : CClosurePrimitive { public: void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) { - closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, weight); + closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight)); sd->flag |= SD_HOLDOUT; } }; diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp index 39fcee1ac0d..667207ec6bf 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp @@ -14,10 +14,15 @@ #include "kernel/osl/closures.h" // clang-format off +#include "kernel/device/cpu/compat.h" +#include "kernel/device/cpu/globals.h" + #include "kernel/types.h" #include "kernel/closure/alloc.h" #include "kernel/closure/bsdf_diffuse_ramp.h" #include "kernel/closure/bsdf_util.h" + +#include "kernel/util/color.h" // clang-format on CCL_NAMESPACE_BEGIN @@ -34,7 +39,7 @@ class DiffuseRampClosure : public CBSDFClosure { params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); DiffuseRampBsdf *bsdf = (DiffuseRampBsdf *)bsdf_alloc_osl( - sd, sizeof(DiffuseRampBsdf), weight, ¶ms); + sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight), ¶ms); if (bsdf) { bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp index 972ed7e4a6d..6f54a96e542 100644 --- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp @@ -14,10 +14,15 @@ #include "kernel/osl/closures.h" // clang-format off +#include "kernel/device/cpu/compat.h" +#include "kernel/device/cpu/globals.h" + #include "kernel/types.h" #include "kernel/closure/alloc.h" #include "kernel/closure/bsdf_phong_ramp.h" #include "kernel/closure/bsdf_util.h" + +#include "kernel/util/color.h" // clang-format on CCL_NAMESPACE_BEGIN @@ -34,7 +39,7 @@ class PhongRampClosure : public CBSDFClosure { params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl( - sd, sizeof(PhongRampBsdf), weight, ¶ms); + sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight), ¶ms); if (bsdf) { bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bssrdf.cpp index 4b282fddad3..3054946ba5a 100644 --- a/intern/cycles/kernel/osl/bssrdf.cpp +++ b/intern/cycles/kernel/osl/bssrdf.cpp @@ -12,6 +12,9 @@ #include "kernel/osl/closures.h" // clang-format off +#include "kernel/device/cpu/compat.h" +#include "kernel/device/cpu/globals.h" + #include "kernel/types.h" #include "kernel/closure/alloc.h" @@ -19,6 +22,8 @@ #include "kernel/closure/bsdf_diffuse.h" #include "kernel/closure/bsdf_principled_diffuse.h" #include "kernel/closure/bssrdf.h" + +#include "kernel/util/color.h" // clang-format on CCL_NAMESPACE_BEGIN @@ -59,14 +64,14 @@ class CBSSRDFClosure : public CClosurePrimitive { void alloc(ShaderData *sd, uint32_t path_flag, float3 weight, ClosureType type) { - Bssrdf *bssrdf = bssrdf_alloc(sd, weight); + Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(weight)); if (bssrdf) { /* disable in case of diffuse ancestor, can't see it well then and * adds considerably noise due to probabilities of continuing path * getting lower and lower */ if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) { - params.radius = make_float3(0.0f, 0.0f, 0.0f); + params.radius = zero_spectrum(); } /* create one closure per color channel */ diff --git a/intern/cycles/kernel/osl/closures.cpp b/intern/cycles/kernel/osl/closures.cpp index 7c6b48154e4..8766fb73dbb 100644 --- a/intern/cycles/kernel/osl/closures.cpp +++ b/intern/cycles/kernel/osl/closures.cpp @@ -38,6 +38,8 @@ #include "kernel/closure/bsdf_principled_diffuse.h" #include "kernel/closure/bsdf_principled_sheen.h" #include "kernel/closure/volume.h" + +#include "kernel/util/color.h" // clang-format on CCL_NAMESPACE_BEGIN @@ -183,7 +185,7 @@ class PrincipledSheenClosure : public CBSDFClosure { params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc_osl( - sd, sizeof(PrincipledSheenBsdf), weight, ¶ms); + sd, sizeof(PrincipledSheenBsdf), rgb_to_spectrum(weight), ¶ms); sd->flag |= (bsdf) ? bsdf_principled_sheen_setup(sd, bsdf) : 0; } } @@ -207,7 +209,7 @@ class PrincipledHairClosure : public CBSDFClosure { PrincipledHairBSDF *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) { PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc_osl( - sd, sizeof(PrincipledHairBSDF), weight, ¶ms); + sd, sizeof(PrincipledHairBSDF), rgb_to_spectrum(weight), ¶ms); if (!bsdf) { return NULL; } @@ -263,7 +265,7 @@ class PrincipledClearcoatClosure : public CBSDFClosure { MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight) { MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), weight, ¶ms); + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); if (!bsdf) { return NULL; } @@ -273,13 +275,13 @@ class PrincipledClearcoatClosure : public CBSDFClosure { return NULL; } - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->extra = extra; bsdf->ior = 1.5f; bsdf->alpha_x = clearcoat_roughness; bsdf->alpha_y = clearcoat_roughness; - bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f); + bsdf->extra->color = zero_spectrum(); + bsdf->extra->cspec0 = make_spectrum(0.04f); bsdf->extra->clearcoat = clearcoat; return bsdf; } @@ -511,7 +513,7 @@ class MicrofacetClosure : public CBSDFClosure { params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), weight, ¶ms); + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); if (!bsdf) { return; @@ -586,7 +588,7 @@ class MicrofacetFresnelClosure : public CBSDFClosure { } MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), weight, ¶ms); + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); if (!bsdf) { return NULL; } @@ -597,8 +599,8 @@ class MicrofacetFresnelClosure : public CBSDFClosure { } bsdf->extra = extra; - bsdf->extra->color = color; - bsdf->extra->cspec0 = cspec0; + bsdf->extra->color = rgb_to_spectrum(color); + bsdf->extra->cspec0 = rgb_to_spectrum(cspec0); bsdf->extra->clearcoat = 0.0f; return bsdf; } @@ -615,7 +617,7 @@ class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure { return; } - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->alpha_y = bsdf->alpha_x; sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd); } @@ -684,7 +686,7 @@ class MicrofacetMultiClosure : public CBSDFClosure { } MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), weight, ¶ms); + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); if (!bsdf) { return NULL; } @@ -695,8 +697,8 @@ class MicrofacetMultiClosure : public CBSDFClosure { } bsdf->extra = extra; - bsdf->extra->color = color; - bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra->color = rgb_to_spectrum(color); + bsdf->extra->cspec0 = zero_spectrum(); bsdf->extra->clearcoat = 0.0f; return bsdf; } @@ -714,7 +716,7 @@ class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure { } bsdf->ior = 0.0f; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->alpha_y = bsdf->alpha_x; sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); } @@ -777,7 +779,7 @@ class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure { return; } - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->alpha_y = bsdf->alpha_x; sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); } @@ -814,7 +816,7 @@ class MicrofacetMultiFresnelClosure : public CBSDFClosure { } MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl( - sd, sizeof(MicrofacetBsdf), weight, ¶ms); + sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight), ¶ms); if (!bsdf) { return NULL; } @@ -825,8 +827,8 @@ class MicrofacetMultiFresnelClosure : public CBSDFClosure { } bsdf->extra = extra; - bsdf->extra->color = color; - bsdf->extra->cspec0 = cspec0; + bsdf->extra->color = rgb_to_spectrum(color); + bsdf->extra->cspec0 = rgb_to_spectrum(cspec0); bsdf->extra->clearcoat = 0.0f; return bsdf; } @@ -843,7 +845,7 @@ class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure { return; } - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->alpha_y = bsdf->alpha_x; sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); } @@ -911,7 +913,7 @@ class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosu return; } - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->alpha_y = bsdf->alpha_x; sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); } @@ -941,7 +943,7 @@ class TransparentClosure : public CBSDFClosure { void setup(ShaderData *sd, uint32_t path_flag, float3 weight) { - bsdf_transparent_setup(sd, weight, path_flag); + bsdf_transparent_setup(sd, rgb_to_spectrum(weight), path_flag); } }; @@ -960,7 +962,7 @@ class VolumeAbsorptionClosure : public CBSDFClosure { public: void setup(ShaderData *sd, uint32_t path_flag, float3 weight) { - volume_extinction_setup(sd, weight); + volume_extinction_setup(sd, rgb_to_spectrum(weight)); } }; @@ -979,10 +981,10 @@ class VolumeHenyeyGreensteinClosure : public CBSDFClosure { void setup(ShaderData *sd, uint32_t path_flag, float3 weight) { - volume_extinction_setup(sd, weight); + volume_extinction_setup(sd, rgb_to_spectrum(weight)); HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc_osl( - sd, sizeof(HenyeyGreensteinVolume), weight, ¶ms); + sd, sizeof(HenyeyGreensteinVolume), rgb_to_spectrum(weight), ¶ms); if (!volume) { return; } diff --git a/intern/cycles/kernel/osl/closures.h b/intern/cycles/kernel/osl/closures.h index e10a3d88a04..97666be7a1e 100644 --- a/intern/cycles/kernel/osl/closures.h +++ b/intern/cycles/kernel/osl/closures.h @@ -115,7 +115,8 @@ class CBSDFClosure : public CClosurePrimitive { { \ if (!skip(sd, path_flag, TYPE)) { \ params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); \ - structname *bsdf = (structname *)bsdf_alloc_osl(sd, sizeof(structname), weight, ¶ms); \ + structname *bsdf = (structname *)bsdf_alloc_osl( \ + sd, sizeof(structname), rgb_to_spectrum(weight), ¶ms); \ sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \ } \ } \ diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 1a01b215836..8d1928d0126 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -14,9 +14,13 @@ // clang-format off #include "kernel/device/cpu/compat.h" +#include "kernel/device/cpu/globals.h" + #include "kernel/types.h" #include "kernel/closure/alloc.h" #include "kernel/closure/emissive.h" + +#include "kernel/util/color.h" // clang-format on CCL_NAMESPACE_BEGIN @@ -34,7 +38,7 @@ class GenericEmissiveClosure : public CClosurePrimitive { public: void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight) { - emission_setup(sd, weight); + emission_setup(sd, rgb_to_spectrum(weight)); } }; diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp index 6b7981b7f3a..6766fe2ce89 100644 --- a/intern/cycles/kernel/osl/services.cpp +++ b/intern/cycles/kernel/osl/services.cpp @@ -1102,8 +1102,9 @@ bool OSLRenderServices::get_background_attribute(const KernelGlobalsCPU *kg, ndc[0] = camera_world_to_ndc(kg, sd, sd->P); if (derivatives) { - ndc[1] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx) - ndc[0]; - ndc[2] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy) - ndc[0]; + const differential3 dP = differential_from_compact(sd->Ng, sd->dP); + ndc[1] = camera_world_to_ndc(kg, sd, sd->P + dP.dx) - ndc[0]; + ndc[2] = camera_world_to_ndc(kg, sd, sd->P + dP.dy) - ndc[0]; } } @@ -1755,11 +1756,13 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, return set_attribute_float3(sd->Ng, type, derivatives, val); } else if (name == u_P) { - float3 f[3] = {sd->P, sd->dP.dx, sd->dP.dy}; + const differential3 dP = differential_from_compact(sd->Ng, sd->dP); + float3 f[3] = {sd->P, dP.dx, dP.dy}; return set_attribute_float3(f, type, derivatives, val); } else if (name == u_I) { - float3 f[3] = {sd->I, sd->dI.dx, sd->dI.dy}; + const differential3 dI = differential_from_compact(sd->I, sd->dI); + float3 f[3] = {sd->I, dI.dx, dI.dy}; return set_attribute_float3(f, type, derivatives, val); } else if (name == u_u) { diff --git a/intern/cycles/kernel/osl/shader.cpp b/intern/cycles/kernel/osl/shader.cpp index af96c0070e3..5862b6a8a2b 100644 --- a/intern/cycles/kernel/osl/shader.cpp +++ b/intern/cycles/kernel/osl/shader.cpp @@ -17,6 +17,8 @@ #include "kernel/osl/globals.h" #include "kernel/osl/services.h" #include "kernel/osl/shader.h" + +#include "kernel/util/differential.h" // clang-format on #include "scene/attribute.h" @@ -79,13 +81,16 @@ static void shaderdata_to_shaderglobals(const KernelGlobalsCPU *kg, { OSL::ShaderGlobals *globals = &tdata->globals; + const differential3 dP = differential_from_compact(sd->Ng, sd->dP); + const differential3 dI = differential_from_compact(sd->I, sd->dI); + /* copy from shader data to shader globals */ globals->P = TO_VEC3(sd->P); - globals->dPdx = TO_VEC3(sd->dP.dx); - globals->dPdy = TO_VEC3(sd->dP.dy); + globals->dPdx = TO_VEC3(dP.dx); + globals->dPdy = TO_VEC3(dP.dy); globals->I = TO_VEC3(sd->I); - globals->dIdx = TO_VEC3(sd->dI.dx); - globals->dIdy = TO_VEC3(sd->dI.dy); + globals->dIdx = TO_VEC3(dI.dx); + globals->dIdy = TO_VEC3(dI.dy); globals->N = TO_VEC3(sd->N); globals->Ng = TO_VEC3(sd->Ng); globals->u = sd->u; @@ -183,9 +188,10 @@ void OSLShader::eval_surface(const KernelGlobalsCPU *kg, /* automatic bump shader */ if (kg->osl->bump_state[shader]) { /* save state */ - float3 P = sd->P; - float3 dPdx = sd->dP.dx; - float3 dPdy = sd->dP.dy; + const float3 P = sd->P; + const float dP = sd->dP; + const OSL::Vec3 dPdx = globals->dPdx; + const OSL::Vec3 dPdy = globals->dPdy; /* set state as if undisplaced */ if (sd->flag & SD_HAS_DISPLACEMENT) { @@ -199,17 +205,20 @@ void OSLShader::eval_surface(const KernelGlobalsCPU *kg, (void)found; assert(found); + differential3 tmp_dP; memcpy(&sd->P, data, sizeof(float) * 3); - memcpy(&sd->dP.dx, data + 3, sizeof(float) * 3); - memcpy(&sd->dP.dy, data + 6, sizeof(float) * 3); + memcpy(&tmp_dP.dx, data + 3, sizeof(float) * 3); + memcpy(&tmp_dP.dy, data + 6, sizeof(float) * 3); object_position_transform(kg, sd, &sd->P); - object_dir_transform(kg, sd, &sd->dP.dx); - object_dir_transform(kg, sd, &sd->dP.dy); + object_dir_transform(kg, sd, &tmp_dP.dx); + object_dir_transform(kg, sd, &tmp_dP.dy); + + sd->dP = differential_make_compact(tmp_dP); globals->P = TO_VEC3(sd->P); - globals->dPdx = TO_VEC3(sd->dP.dx); - globals->dPdy = TO_VEC3(sd->dP.dy); + globals->dPdx = TO_VEC3(tmp_dP.dx); + globals->dPdy = TO_VEC3(tmp_dP.dy); } /* execute bump shader */ @@ -217,8 +226,7 @@ void OSLShader::eval_surface(const KernelGlobalsCPU *kg, /* reset state */ sd->P = P; - sd->dP.dx = dPdx; - sd->dP.dy = dPdy; + sd->dP = dP; globals->P = TO_VEC3(P); globals->dPdx = TO_VEC3(dPdx); diff --git a/intern/cycles/kernel/sample/jitter.h b/intern/cycles/kernel/sample/jitter.h index b5cfa624406..dd170cf2120 100644 --- a/intern/cycles/kernel/sample/jitter.h +++ b/intern/cycles/kernel/sample/jitter.h @@ -1,20 +1,12 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ +#include "kernel/sample/util.h" +#include "util/hash.h" + #pragma once CCL_NAMESPACE_BEGIN -ccl_device_inline uint32_t laine_karras_permutation(uint32_t x, uint32_t seed) -{ - x += seed; - x ^= (x * 0x6c50b47cu); - x ^= x * 0xb82f1e52u; - x ^= x * 0xc7afe638u; - x ^= x * 0x8d22f6e6u; - - return x; -} - ccl_device_inline uint32_t nested_uniform_scramble(uint32_t x, uint32_t seed) { x = reverse_integer_bits(x); @@ -24,46 +16,6 @@ ccl_device_inline uint32_t nested_uniform_scramble(uint32_t x, uint32_t seed) return x; } -ccl_device_inline uint cmj_hash(uint i, uint p) -{ - i ^= p; - i ^= i >> 17; - i ^= i >> 10; - i *= 0xb36534e5; - i ^= i >> 12; - i ^= i >> 21; - i *= 0x93fc4795; - i ^= 0xdf6e307f; - i ^= i >> 17; - i *= 1 | p >> 18; - - return i; -} - -ccl_device_inline uint cmj_hash_simple(uint i, uint p) -{ - i = (i ^ 61) ^ p; - i += i << 3; - i ^= i >> 4; - i *= 0x27d4eb2d; - return i; -} - -ccl_device_inline float cmj_randfloat(uint i, uint p) -{ - return cmj_hash(i, p) * (1.0f / 4294967808.0f); -} - -ccl_device_inline float cmj_randfloat_simple(uint i, uint p) -{ - return cmj_hash_simple(i, p) * (1.0f / (float)0xFFFFFFFF); -} - -ccl_device_inline float cmj_randfloat_simple_dist(uint i, uint p, float d) -{ - return cmj_hash_simple(i, p) * (d / (float)0xFFFFFFFF); -} - ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uint dimension) { uint hash = rng_hash; @@ -71,16 +23,12 @@ ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uin if (kernel_data.integrator.scrambling_distance < 1.0f) { hash = kernel_data.integrator.seed; - jitter_x = cmj_randfloat_simple_dist( - dimension, rng_hash, kernel_data.integrator.scrambling_distance); + jitter_x = hash_wang_seeded_float(dimension, rng_hash) * + kernel_data.integrator.scrambling_distance; } /* Perform Owen shuffle of the sample number to reorder the samples. */ -#ifdef _SIMPLE_HASH_ - const uint rv = cmj_hash_simple(dimension, hash); -#else /* Use a _REGULAR_HASH_. */ - const uint rv = cmj_hash(dimension, hash); -#endif + const uint rv = hash_cmj_seeded_uint(dimension, hash); #ifdef _XOR_SHUFFLE_ # warning "Using XOR shuffle." const uint s = sample ^ rv; @@ -101,11 +49,7 @@ ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uin #ifndef _NO_CRANLEY_PATTERSON_ROTATION_ /* Use Cranley-Patterson rotation to displace the sample pattern. */ -# ifdef _SIMPLE_HASH_ - float dx = cmj_randfloat_simple(d, hash); -# else - float dx = cmj_randfloat(d, hash); -# endif + float dx = hash_cmj_seeded_float(d, hash); /* Jitter sample locations and map back into [0 1]. */ fx = fx + dx + jitter_x; fx = fx - floorf(fx); @@ -129,18 +73,14 @@ ccl_device void pmj_sample_2D(KernelGlobals kg, if (kernel_data.integrator.scrambling_distance < 1.0f) { hash = kernel_data.integrator.seed; - jitter_x = cmj_randfloat_simple_dist( - dimension, rng_hash, kernel_data.integrator.scrambling_distance); - jitter_y = cmj_randfloat_simple_dist( - dimension + 1, rng_hash, kernel_data.integrator.scrambling_distance); + jitter_x = hash_wang_seeded_float(dimension, rng_hash) * + kernel_data.integrator.scrambling_distance; + jitter_y = hash_wang_seeded_float(dimension + 1, rng_hash) * + kernel_data.integrator.scrambling_distance; } /* Perform a shuffle on the sample number to reorder the samples. */ -#ifdef _SIMPLE_HASH_ - const uint rv = cmj_hash_simple(dimension, hash); -#else /* Use a _REGULAR_HASH_. */ - const uint rv = cmj_hash(dimension, hash); -#endif + const uint rv = hash_cmj_seeded_uint(dimension, hash); #ifdef _XOR_SHUFFLE_ # warning "Using XOR shuffle." const uint s = sample ^ rv; @@ -159,13 +99,8 @@ ccl_device void pmj_sample_2D(KernelGlobals kg, #ifndef _NO_CRANLEY_PATTERSON_ROTATION_ /* Use Cranley-Patterson rotation to displace the sample pattern. */ -# ifdef _SIMPLE_HASH_ - float dx = cmj_randfloat_simple(d, hash); - float dy = cmj_randfloat_simple(d + 1, hash); -# else - float dx = cmj_randfloat(d, hash); - float dy = cmj_randfloat(d + 1, hash); -# endif + float dx = hash_cmj_seeded_float(d, hash); + float dy = hash_cmj_seeded_float(d + 1, hash); /* Jitter sample locations and map back to the unit square [0 1]x[0 1]. */ float sx = fx + dx + jitter_x; float sy = fy + dy + jitter_y; diff --git a/intern/cycles/kernel/sample/pattern.h b/intern/cycles/kernel/sample/pattern.h index 89500d51872..e8c3acb5cf7 100644 --- a/intern/cycles/kernel/sample/pattern.h +++ b/intern/cycles/kernel/sample/pattern.h @@ -4,6 +4,7 @@ #pragma once #include "kernel/sample/jitter.h" +#include "kernel/sample/sobol_burley.h" #include "util/hash.h" CCL_NAMESPACE_BEGIN @@ -48,6 +49,10 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals kg, return (float)drand48(); #endif + if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { + return sobol_burley_sample_1D(sample, dimension, rng_hash); + } + #ifdef __SOBOL__ if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_PMJ) #endif @@ -66,7 +71,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals kg, /* Hash rng with dimension to solve correlation issues. * See T38710, T50116. */ - uint tmp_rng = cmj_hash_simple(dimension, rng_hash); + uint tmp_rng = hash_wang_seeded_uint(dimension, rng_hash); shift = tmp_rng * (kernel_data.integrator.scrambling_distance / (float)0xFFFFFFFF); return r + shift - floorf(r + shift); @@ -86,6 +91,11 @@ ccl_device_forceinline void path_rng_2D(KernelGlobals kg, return; #endif + if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { + sobol_burley_sample_2D(sample, dimension, rng_hash, fx, fy); + return; + } + #ifdef __SOBOL__ if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_PMJ) #endif diff --git a/intern/cycles/kernel/sample/sobol_burley.h b/intern/cycles/kernel/sample/sobol_burley.h new file mode 100644 index 00000000000..4e041aa075e --- /dev/null +++ b/intern/cycles/kernel/sample/sobol_burley.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +/* + * A shuffled, Owen-scrambled Sobol sampler, implemented with the + * techniques from the paper "Practical Hash-based Owen Scrambling" + * by Brent Burley, 2020, Journal of Computer Graphics Techniques. + * + * Note that unlike a standard high-dimensional Sobol sequence, this + * Sobol sampler uses padding to achieve higher dimensions, as described + * in Burley's paper. + */ + +#pragma once + +#include "kernel/sample/util.h" +#include "util/hash.h" +#include "util/math.h" +#include "util/types.h" + +CCL_NAMESPACE_BEGIN + +/* + * Computes a single dimension of a sample from an Owen-scrambled + * Sobol sequence. This is used in the main sampling functions, + * sobol_burley_sample_#D(), below. + * + * - rev_bit_index: the sample index, with reversed order bits. + * - dimension: the sample dimension. + * - scramble_seed: the Owen scrambling seed. + * + * Note that the seed must be well randomized before being + * passed to this function. + */ +ccl_device_forceinline float sobol_burley(uint rev_bit_index, uint dimension, uint scramble_seed) +{ + uint result = 0; + + if (dimension == 0) { + // Fast-path for dimension 0, which is just Van der corput. + // This makes a notable difference in performance since we reuse + // dimensions for padding, and dimension 0 is reused the most. + result = reverse_integer_bits(rev_bit_index); + } + else { + uint i = 0; + while (rev_bit_index != 0) { + uint j = count_leading_zeros(rev_bit_index); + result ^= sobol_burley_table[dimension][i + j]; + i += j + 1; + + // We can't do "<<= j + 1" because that can overflow the shift + // operator, which doesn't do what we need on at least x86. + rev_bit_index <<= j; + rev_bit_index <<= 1; + } + } + + // Apply Owen scrambling. + result = reverse_integer_bits(reversed_bit_owen(result, scramble_seed)); + + return uint_to_float_excl(result); +} + +/* + * Computes a 1D Owen-scrambled and shuffled Sobol sample. + */ +ccl_device float sobol_burley_sample_1D(uint index, uint dimension, uint seed) +{ + // Include the dimension in the seed, so we get decorrelated + // sequences for different dimensions via shuffling. + seed ^= hash_hp_uint(dimension); + + // Shuffle. + index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xbff95bfe); + + return sobol_burley(index, 0, seed ^ 0x635c77bd); +} + +/* + * Computes a 2D Owen-scrambled and shuffled Sobol sample. + */ +ccl_device void sobol_burley_sample_2D( + uint index, uint dimension_set, uint seed, ccl_private float *x, ccl_private float *y) +{ + // Include the dimension set in the seed, so we get decorrelated + // sequences for different dimension sets via shuffling. + seed ^= hash_hp_uint(dimension_set); + + // Shuffle. + index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xf8ade99a); + + *x = sobol_burley(index, 0, seed ^ 0xe0aaaf76); + *y = sobol_burley(index, 1, seed ^ 0x94964d4e); +} + +/* + * Computes a 3D Owen-scrambled and shuffled Sobol sample. + */ +ccl_device void sobol_burley_sample_3D(uint index, + uint dimension_set, + uint seed, + ccl_private float *x, + ccl_private float *y, + ccl_private float *z) +{ + // Include the dimension set in the seed, so we get decorrelated + // sequences for different dimension sets via shuffling. + seed ^= hash_hp_uint(dimension_set); + + // Shuffle. + index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xcaa726ac); + + *x = sobol_burley(index, 0, seed ^ 0x9e78e391); + *y = sobol_burley(index, 1, seed ^ 0x67c33241); + *z = sobol_burley(index, 2, seed ^ 0x78c395c5); +} + +/* + * Computes a 4D Owen-scrambled and shuffled Sobol sample. + */ +ccl_device void sobol_burley_sample_4D(uint index, + uint dimension_set, + uint seed, + ccl_private float *x, + ccl_private float *y, + ccl_private float *z, + ccl_private float *w) +{ + // Include the dimension set in the seed, so we get decorrelated + // sequences for different dimension sets via shuffling. + seed ^= hash_hp_uint(dimension_set); + + // Shuffle. + index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xc2c1a055); + + *x = sobol_burley(index, 0, seed ^ 0x39468210); + *y = sobol_burley(index, 1, seed ^ 0xe9d8a845); + *z = sobol_burley(index, 2, seed ^ 0x5f32b482); + *w = sobol_burley(index, 3, seed ^ 0x1524cc56); +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/sample/util.h b/intern/cycles/kernel/sample/util.h new file mode 100644 index 00000000000..33056bb7819 --- /dev/null +++ b/intern/cycles/kernel/sample/util.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +#include "util/types.h" + +CCL_NAMESPACE_BEGIN + +/* + * Performs base-2 Owen scrambling on a reversed-bit integer. + * + * This is equivalent to the Laine-Karras permutation, but much higher + * quality. See https://psychopath.io/post/2021_01_30_building_a_better_lk_hash + */ +ccl_device_inline uint reversed_bit_owen(uint n, uint seed) +{ + n ^= n * 0x3d20adea; + n += seed; + n *= (seed >> 16) | 1; + n ^= n * 0x05526c56; + n ^= n * 0x53a22864; + + return n; +} + +/* + * Performs base-2 Owen scrambling on a reversed-bit integer. + * + * This is here for backwards-compatibility, and can be replaced + * with reversed_bit_owen() above at some point. + * See https://developer.blender.org/D15679#426304 + */ +ccl_device_inline uint laine_karras_permutation(uint x, uint seed) +{ + x += seed; + x ^= (x * 0x6c50b47cu); + x ^= x * 0xb82f1e52u; + x ^= x * 0xc7afe638u; + x ^= x * 0x8d22f6e6u; + + return x; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/attribute.h b/intern/cycles/kernel/svm/attribute.h index a3609d8b4b0..5f0d1609f08 100644 --- a/intern/cycles/kernel/svm/attribute.h +++ b/intern/cycles/kernel/svm/attribute.h @@ -140,6 +140,16 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg, } } +ccl_device_forceinline float3 svm_node_bump_P_dx(const ccl_private ShaderData *sd) +{ + return sd->P + differential_from_compact(sd->Ng, sd->dP).dx; +} + +ccl_device_forceinline float3 svm_node_bump_P_dy(const ccl_private ShaderData *sd) +{ + return sd->P + differential_from_compact(sd->Ng, sd->dP).dy; +} + ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, @@ -167,7 +177,7 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg, if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) { /* No generated attribute, fall back to object coordinates. */ - float3 f = sd->P + sd->dP.dx; + float3 f = svm_node_bump_P_dx(sd); if (sd->object != OBJECT_NONE) { object_inverse_position_transform(kg, sd, &f); } @@ -265,7 +275,7 @@ ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg, if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) { /* No generated attribute, fall back to object coordinates. */ - float3 f = sd->P + sd->dP.dy; + float3 f = svm_node_bump_P_dy(sd); if (sd->object != OBJECT_NONE) { object_inverse_position_transform(kg, sd, &f); } diff --git a/intern/cycles/kernel/svm/bump.h b/intern/cycles/kernel/svm/bump.h index 566c45f5f25..1009a6a4241 100644 --- a/intern/cycles/kernel/svm/bump.h +++ b/intern/cycles/kernel/svm/bump.h @@ -14,23 +14,21 @@ ccl_device_noinline void svm_node_enter_bump_eval(KernelGlobals kg, { /* save state */ stack_store_float3(stack, offset + 0, sd->P); - stack_store_float3(stack, offset + 3, sd->dP.dx); - stack_store_float3(stack, offset + 6, sd->dP.dy); + stack_store_float(stack, offset + 3, sd->dP); /* set state as if undisplaced */ const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POSITION_UNDISPLACED); if (desc.offset != ATTR_STD_NOT_FOUND) { - float3 P, dPdx, dPdy; - P = primitive_surface_attribute_float3(kg, sd, desc, &dPdx, &dPdy); + differential3 dP; + float3 P = primitive_surface_attribute_float3(kg, sd, desc, &dP.dx, &dP.dy); object_position_transform(kg, sd, &P); - object_dir_transform(kg, sd, &dPdx); - object_dir_transform(kg, sd, &dPdy); + object_dir_transform(kg, sd, &dP.dx); + object_dir_transform(kg, sd, &dP.dy); sd->P = P; - sd->dP.dx = dPdx; - sd->dP.dy = dPdy; + sd->dP = differential_make_compact(dP); } } @@ -41,8 +39,7 @@ ccl_device_noinline void svm_node_leave_bump_eval(KernelGlobals kg, { /* restore state */ sd->P = stack_load_float3(stack, offset + 0); - sd->dP.dx = stack_load_float3(stack, offset + 3); - sd->dP.dy = stack_load_float3(stack, offset + 6); + sd->dP = stack_load_float(stack, offset + 3); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 99a8fdd3be9..5e8ef69fd15 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -3,6 +3,8 @@ #pragma once +#include "kernel/util/color.h" + CCL_NAMESPACE_BEGIN /* Closure Nodes */ @@ -183,7 +185,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, } float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? stack_load_float3(stack, data_cn_ssr.y) : - make_float3(1.0f, 1.0f, 1.0f); + one_float3(); float subsurface_ior = stack_valid(data_cn_ssr.z) ? stack_load_float(stack, data_cn_ssr.z) : 1.4f; float subsurface_anisotropy = stack_valid(data_cn_ssr.w) ? @@ -198,12 +200,12 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, __uint_as_float(data_subsurface_color.z), __uint_as_float(data_subsurface_color.w)); - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; # ifdef __SUBSURFACE__ float3 mixed_ss_base_color = subsurface_color * subsurface + base_color * (1.0f - subsurface); - float3 subsurf_weight = weight * mixed_ss_base_color * diffuse_weight; + Spectrum subsurf_weight = weight * rgb_to_spectrum(mixed_ss_base_color) * diffuse_weight; /* disable in case of diffuse ancestor, can't see it well then and * adds considerably noise due to probabilities of continuing path @@ -220,7 +222,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, /* diffuse */ if (fabsf(average(mixed_ss_base_color)) > CLOSURE_WEIGHT_CUTOFF) { if (subsurface <= CLOSURE_WEIGHT_CUTOFF && diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { - float3 diff_weight = weight * base_color * diffuse_weight; + Spectrum diff_weight = weight * rgb_to_spectrum(base_color) * diffuse_weight; ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *) bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), diff_weight); @@ -237,8 +239,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, subsurf_weight); if (bssrdf) { - bssrdf->radius = subsurface_radius * subsurface; - bssrdf->albedo = mixed_ss_base_color; + bssrdf->radius = rgb_to_spectrum(subsurface_radius * subsurface); + bssrdf->albedo = rgb_to_spectrum(mixed_ss_base_color); bssrdf->N = N; bssrdf->roughness = roughness; @@ -254,7 +256,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, # else /* diffuse */ if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF) { - float3 diff_weight = weight * base_color * diffuse_weight; + Spectrum diff_weight = weight * rgb_to_spectrum(base_color) * diffuse_weight; ccl_private PrincipledDiffuseBsdf *bsdf = (ccl_private PrincipledDiffuseBsdf *)bsdf_alloc( sd, sizeof(PrincipledDiffuseBsdf), diff_weight); @@ -272,15 +274,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, /* sheen */ if (diffuse_weight > CLOSURE_WEIGHT_CUTOFF && sheen > CLOSURE_WEIGHT_CUTOFF) { float m_cdlum = linear_rgb_to_gray(kg, base_color); - float3 m_ctint = m_cdlum > 0.0f ? - base_color / m_cdlum : - make_float3(1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat + float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : + one_float3(); // normalize lum. to isolate hue+sat /* color of the sheen component */ - float3 sheen_color = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - sheen_tint) + - m_ctint * sheen_tint; + float3 sheen_color = make_float3(1.0f - sheen_tint) + m_ctint * sheen_tint; - float3 sheen_weight = weight * sheen * sheen_color * diffuse_weight; + Spectrum sheen_weight = weight * sheen * rgb_to_spectrum(sheen_color) * diffuse_weight; ccl_private PrincipledSheenBsdf *bsdf = (ccl_private PrincipledSheenBsdf *)bsdf_alloc( sd, sizeof(PrincipledSheenBsdf), sheen_weight); @@ -299,7 +299,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, # endif if (specular_weight > CLOSURE_WEIGHT_CUTOFF && (specular > CLOSURE_WEIGHT_CUTOFF || metallic > CLOSURE_WEIGHT_CUTOFF)) { - float3 spec_weight = weight * specular_weight; + Spectrum spec_weight = weight * specular_weight; ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( sd, sizeof(MicrofacetBsdf), spec_weight); @@ -322,16 +322,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, float m_cdlum = 0.3f * base_color.x + 0.6f * base_color.y + 0.1f * base_color.z; // luminance approx. - float3 m_ctint = m_cdlum > 0.0f ? - base_color / m_cdlum : - make_float3( - 1.0f, 1.0f, 1.0f); // normalize lum. to isolate hue+sat - float3 tmp_col = make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint) + - m_ctint * specular_tint; - - bsdf->extra->cspec0 = (specular * 0.08f * tmp_col) * (1.0f - metallic) + - base_color * metallic; - bsdf->extra->color = base_color; + float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : + one_float3(); // normalize lum. to isolate hue+sat + float3 tmp_col = make_float3(1.0f - specular_tint) + m_ctint * specular_tint; + + bsdf->extra->cspec0 = rgb_to_spectrum( + (specular * 0.08f * tmp_col) * (1.0f - metallic) + base_color * metallic); + bsdf->extra->color = rgb_to_spectrum(base_color); bsdf->extra->clearcoat = 0.0f; /* setup bsdf */ @@ -352,9 +349,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, kernel_data.integrator.caustics_refractive || (path_flag & PATH_RAY_DIFFUSE) == 0) { # endif if (final_transmission > CLOSURE_WEIGHT_CUTOFF) { - float3 glass_weight = weight * final_transmission; - float3 cspec0 = base_color * specular_tint + - make_float3(1.0f, 1.0f, 1.0f) * (1.0f - specular_tint); + Spectrum glass_weight = weight * final_transmission; + float3 cspec0 = base_color * specular_tint + make_float3(1.0f - specular_tint); if (roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { /* use single-scatter GGX */ @@ -374,15 +370,15 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (bsdf && extra) { bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->extra = extra; bsdf->alpha_x = refl_roughness * refl_roughness; bsdf->alpha_y = refl_roughness * refl_roughness; bsdf->ior = ior; - bsdf->extra->color = base_color; - bsdf->extra->cspec0 = cspec0; + bsdf->extra->color = rgb_to_spectrum(base_color); + bsdf->extra->cspec0 = rgb_to_spectrum(cspec0); bsdf->extra->clearcoat = 0.0f; /* setup bsdf */ @@ -398,10 +394,12 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, /* This is to prevent MNEE from receiving a null BSDF. */ float refraction_fresnel = fmaxf(0.0001f, 1.0f - fresnel); ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), base_color * glass_weight * refraction_fresnel); + sd, + sizeof(MicrofacetBsdf), + rgb_to_spectrum(base_color) * glass_weight * refraction_fresnel); if (bsdf) { bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->extra = NULL; if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) @@ -430,14 +428,14 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (bsdf && extra) { bsdf->N = N; bsdf->extra = extra; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->alpha_x = roughness * roughness; bsdf->alpha_y = roughness * roughness; bsdf->ior = ior; - bsdf->extra->color = base_color; - bsdf->extra->cspec0 = cspec0; + bsdf->extra->color = rgb_to_spectrum(base_color); + bsdf->extra->cspec0 = rgb_to_spectrum(cspec0); bsdf->extra->clearcoat = 0.0f; /* setup bsdf */ @@ -463,15 +461,15 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (bsdf && extra) { bsdf->N = clearcoat_normal; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->ior = 1.5f; bsdf->extra = extra; bsdf->alpha_x = clearcoat_roughness * clearcoat_roughness; bsdf->alpha_y = clearcoat_roughness * clearcoat_roughness; - bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f); - bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f); + bsdf->extra->color = zero_spectrum(); + bsdf->extra->cspec0 = make_spectrum(0.04f); bsdf->extra->clearcoat = clearcoat; /* setup bsdf */ @@ -486,7 +484,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, } #endif /* __PRINCIPLED__ */ case CLOSURE_BSDF_DIFFUSE_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private OrenNayarBsdf *bsdf = (ccl_private OrenNayarBsdf *)bsdf_alloc( sd, sizeof(OrenNayarBsdf), weight); @@ -506,7 +504,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, break; } case CLOSURE_BSDF_TRANSLUCENT_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc( sd, sizeof(DiffuseBsdf), weight); @@ -517,7 +515,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, break; } case CLOSURE_BSDF_TRANSPARENT_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; bsdf_transparent_setup(sd, weight, path_flag); break; } @@ -530,7 +528,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( sd, sizeof(MicrofacetBsdf), weight); @@ -545,7 +543,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, bsdf->extra = NULL; if (data_node.y == SVM_STACK_INVALID) { - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->alpha_x = roughness; bsdf->alpha_y = roughness; } @@ -581,8 +579,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, bsdf->extra = (ccl_private MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra)); if (bsdf->extra) { - bsdf->extra->color = stack_load_float3(stack, data_node.w); - bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra->color = rgb_to_spectrum(stack_load_float3(stack, data_node.w)); + bsdf->extra->cspec0 = zero_spectrum(); bsdf->extra->clearcoat = 0.0f; sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); } @@ -600,13 +598,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (!kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( sd, sizeof(MicrofacetBsdf), weight); if (bsdf) { bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->extra = NULL; float eta = fmaxf(param2, 1e-5f); @@ -644,7 +642,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, break; } #endif - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; /* index of refraction */ float eta = fmaxf(param2, 1e-5f); @@ -665,7 +663,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (bsdf) { bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->extra = NULL; svm_node_glass_setup(sd, bsdf, type, eta, roughness, false); } @@ -683,7 +681,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (bsdf) { bsdf->N = N; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); bsdf->extra = NULL; svm_node_glass_setup(sd, bsdf, type, eta, roughness, true); } @@ -697,7 +695,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) break; #endif - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( sd, sizeof(MicrofacetBsdf), weight); if (!bsdf) { @@ -712,7 +710,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, bsdf->N = N; bsdf->extra = extra; - bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->T = zero_float3(); float roughness = sqr(param1); bsdf->alpha_x = roughness; @@ -721,8 +719,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; kernel_assert(stack_valid(data_node.z)); - bsdf->extra->color = stack_load_float3(stack, data_node.z); - bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra->color = rgb_to_spectrum(stack_load_float3(stack, data_node.z)); + bsdf->extra->cspec0 = zero_spectrum(); bsdf->extra->clearcoat = 0.0f; /* setup bsdf */ @@ -730,7 +728,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, break; } case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private VelvetBsdf *bsdf = (ccl_private VelvetBsdf *)bsdf_alloc( sd, sizeof(VelvetBsdf), weight); @@ -749,7 +747,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, ATTR_FALLTHROUGH; #endif case CLOSURE_BSDF_DIFFUSE_TOON_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private ToonBsdf *bsdf = (ccl_private ToonBsdf *)bsdf_alloc( sd, sizeof(ToonBsdf), weight); @@ -771,7 +769,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, uint4 data_node3 = read_node(kg, &offset); uint4 data_node4 = read_node(kg, &offset); - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; uint offset_ofs, ior_ofs, color_ofs, parametrization; svm_unpack_node_uchar4(data_node.y, &offset_ofs, &ior_ofs, &color_ofs, ¶metrization); @@ -829,7 +827,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, switch (parametrization) { case NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION: { float3 absorption_coefficient = stack_load_float3(stack, absorption_coefficient_ofs); - bsdf->sigma = absorption_coefficient; + bsdf->sigma = rgb_to_spectrum(absorption_coefficient); break; } case NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION: { @@ -849,20 +847,21 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, /* Benedikt Bitterli's melanin ratio remapping. */ float eumelanin = melanin * (1.0f - melanin_redness); float pheomelanin = melanin * melanin_redness; - float3 melanin_sigma = bsdf_principled_hair_sigma_from_concentration(eumelanin, - pheomelanin); + Spectrum melanin_sigma = bsdf_principled_hair_sigma_from_concentration(eumelanin, + pheomelanin); /* Optional tint. */ float3 tint = stack_load_float3(stack, tint_ofs); - float3 tint_sigma = bsdf_principled_hair_sigma_from_reflectance(tint, - radial_roughness); + Spectrum tint_sigma = bsdf_principled_hair_sigma_from_reflectance( + rgb_to_spectrum(tint), radial_roughness); bsdf->sigma = melanin_sigma + tint_sigma; break; } case NODE_PRINCIPLED_HAIR_REFLECTANCE: { float3 color = stack_load_float3(stack, color_ofs); - bsdf->sigma = bsdf_principled_hair_sigma_from_reflectance(color, radial_roughness); + bsdf->sigma = bsdf_principled_hair_sigma_from_reflectance(rgb_to_spectrum(color), + radial_roughness); break; } default: { @@ -879,7 +878,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, } case CLOSURE_BSDF_HAIR_REFLECTION_ID: case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private HairBsdf *bsdf = (ccl_private HairBsdf *)bsdf_alloc( sd, sizeof(HairBsdf), weight); @@ -916,7 +915,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, case CLOSURE_BSSRDF_BURLEY_ID: case CLOSURE_BSSRDF_RANDOM_WALK_ID: case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: { - float3 weight = sd->svm_closure_weight * mix_weight; + Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight); if (bssrdf) { @@ -926,7 +925,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) param1 = 0.0f; - bssrdf->radius = stack_load_float3(stack, data_node.z) * param1; + bssrdf->radius = rgb_to_spectrum(stack_load_float3(stack, data_node.z) * param1); bssrdf->albedo = sd->svm_closure_weight; bssrdf->N = N; bssrdf->roughness = FLT_MAX; @@ -976,10 +975,10 @@ ccl_device_noinline void svm_node_closure_volume(KernelGlobals kg, density = mix_weight * fmaxf(density, 0.0f); /* Compute scattering coefficient. */ - float3 weight = sd->svm_closure_weight; + Spectrum weight = sd->svm_closure_weight; if (type == CLOSURE_VOLUME_ABSORPTION_ID) { - weight = make_float3(1.0f, 1.0f, 1.0f) - weight; + weight = one_spectrum() - weight; } weight *= density; @@ -1047,11 +1046,11 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg, if (density > CLOSURE_WEIGHT_CUTOFF) { /* Compute scattering color. */ - float3 color = sd->svm_closure_weight; + Spectrum color = sd->svm_closure_weight; const AttributeDescriptor attr_color = find_attribute(kg, sd, attr_node.y); if (attr_color.offset != ATTR_STD_NOT_FOUND) { - color *= primitive_volume_attribute_float3(kg, sd, attr_color); + color *= rgb_to_spectrum(primitive_volume_attribute_float3(kg, sd, attr_color)); } /* Add closure for volume scattering. */ @@ -1066,10 +1065,13 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg, } /* Add extinction weight. */ - float3 zero = make_float3(0.0f, 0.0f, 0.0f); - float3 one = make_float3(1.0f, 1.0f, 1.0f); - float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), zero); - float3 absorption = max(one - color, zero) * max(one - absorption_color, zero); + float3 absorption_color = max(sqrt(stack_load_float3(stack, absorption_color_offset)), + zero_float3()); + + Spectrum zero = zero_spectrum(); + Spectrum one = one_spectrum(); + Spectrum absorption = max(one - color, zero) * + max(one - rgb_to_spectrum(absorption_color), zero); volume_extinction_setup(sd, (color + absorption) * density); } @@ -1089,7 +1091,7 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg, if (emission > CLOSURE_WEIGHT_CUTOFF) { float3 emission_color = stack_load_float3(stack, emission_color_offset); - emission_setup(sd, emission * emission_color); + emission_setup(sd, rgb_to_spectrum(emission * emission_color)); } if (blackbody > CLOSURE_WEIGHT_CUTOFF) { @@ -1113,7 +1115,7 @@ ccl_device_noinline int svm_node_principled_volume(KernelGlobals kg, float3 blackbody_tint = stack_load_float3(stack, node.w); float3 bb = blackbody_tint * intensity * rec709_to_rgb(kg, svm_math_blackbody_color_rec709(T)); - emission_setup(sd, bb); + emission_setup(sd, rgb_to_spectrum(bb)); } } #endif @@ -1125,7 +1127,7 @@ ccl_device_noinline void svm_node_closure_emission(ccl_private ShaderData *sd, uint4 node) { uint mix_weight_offset = node.y; - float3 weight = sd->svm_closure_weight; + Spectrum weight = sd->svm_closure_weight; if (stack_valid(mix_weight_offset)) { float mix_weight = stack_load_float(stack, mix_weight_offset); @@ -1144,7 +1146,7 @@ ccl_device_noinline void svm_node_closure_background(ccl_private ShaderData *sd, uint4 node) { uint mix_weight_offset = node.y; - float3 weight = sd->svm_closure_weight; + Spectrum weight = sd->svm_closure_weight; if (stack_valid(mix_weight_offset)) { float mix_weight = stack_load_float(stack, mix_weight_offset); @@ -1181,14 +1183,15 @@ ccl_device_noinline void svm_node_closure_holdout(ccl_private ShaderData *sd, /* Closure Nodes */ -ccl_device_inline void svm_node_closure_store_weight(ccl_private ShaderData *sd, float3 weight) +ccl_device_inline void svm_node_closure_store_weight(ccl_private ShaderData *sd, Spectrum weight) { sd->svm_closure_weight = weight; } ccl_device void svm_node_closure_set_weight(ccl_private ShaderData *sd, uint r, uint g, uint b) { - float3 weight = make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b)); + Spectrum weight = rgb_to_spectrum( + make_float3(__uint_as_float(r), __uint_as_float(g), __uint_as_float(b))); svm_node_closure_store_weight(sd, weight); } @@ -1196,7 +1199,7 @@ ccl_device void svm_node_closure_weight(ccl_private ShaderData *sd, ccl_private float *stack, uint weight_offset) { - float3 weight = stack_load_float3(stack, weight_offset); + Spectrum weight = rgb_to_spectrum(stack_load_float3(stack, weight_offset)); svm_node_closure_store_weight(sd, weight); } @@ -1209,7 +1212,7 @@ ccl_device_noinline void svm_node_emission_weight(KernelGlobals kg, uint strength_offset = node.z; float strength = stack_load_float(stack, strength_offset); - float3 weight = stack_load_float3(stack, color_offset) * strength; + Spectrum weight = rgb_to_spectrum(stack_load_float3(stack, color_offset)) * strength; svm_node_closure_store_weight(sd, weight); } diff --git a/intern/cycles/kernel/svm/displace.h b/intern/cycles/kernel/svm/displace.h index 128023263fd..230f8c73820 100644 --- a/intern/cycles/kernel/svm/displace.h +++ b/intern/cycles/kernel/svm/displace.h @@ -24,18 +24,17 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg, float3 normal_in = stack_valid(normal_offset) ? stack_load_float3(stack, normal_offset) : sd->N; - float3 dPdx = sd->dP.dx; - float3 dPdy = sd->dP.dy; + differential3 dP = differential_from_compact(sd->Ng, sd->dP); if (use_object_space) { object_inverse_normal_transform(kg, sd, &normal_in); - object_inverse_dir_transform(kg, sd, &dPdx); - object_inverse_dir_transform(kg, sd, &dPdy); + object_inverse_dir_transform(kg, sd, &dP.dx); + object_inverse_dir_transform(kg, sd, &dP.dy); } /* get surface tangents from normal */ - float3 Rx = cross(dPdy, normal_in); - float3 Ry = cross(normal_in, dPdx); + float3 Rx = cross(dP.dy, normal_in); + float3 Ry = cross(normal_in, dP.dx); /* get bump values */ uint c_offset, x_offset, y_offset, strength_offset; @@ -46,7 +45,7 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg, float h_y = stack_load_float(stack, y_offset); /* compute surface gradient and determinant */ - float det = dot(dPdx, Rx); + float det = dot(dP.dx, Rx); float3 surfgrad = (h_x - h_c) * Rx + (h_y - h_c) * Ry; float absdet = fabsf(det); diff --git a/intern/cycles/kernel/svm/geometry.h b/intern/cycles/kernel/svm/geometry.h index bbefdcfa755..cbd87d84409 100644 --- a/intern/cycles/kernel/svm/geometry.h +++ b/intern/cycles/kernel/svm/geometry.h @@ -54,7 +54,7 @@ ccl_device_noinline void svm_node_geometry_bump_dx(KernelGlobals kg, switch (type) { case NODE_GEOM_P: - data = sd->P + sd->dP.dx; + data = svm_node_bump_P_dx(sd); break; case NODE_GEOM_uv: data = make_float3(1.0f - sd->u - sd->du.dx - sd->v - sd->dv.dx, sd->u + sd->du.dx, 0.0f); @@ -81,7 +81,7 @@ ccl_device_noinline void svm_node_geometry_bump_dy(KernelGlobals kg, switch (type) { case NODE_GEOM_P: - data = sd->P + sd->dP.dy; + data = svm_node_bump_P_dy(sd); break; case NODE_GEOM_uv: data = make_float3(1.0f - sd->u - sd->du.dy - sd->v - sd->dv.dy, sd->u + sd->du.dy, 0.0f); diff --git a/intern/cycles/kernel/svm/tex_coord.h b/intern/cycles/kernel/svm/tex_coord.h index 2a0130e11d4..8154c542e6f 100644 --- a/intern/cycles/kernel/svm/tex_coord.h +++ b/intern/cycles/kernel/svm/tex_coord.h @@ -106,7 +106,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg, switch (type) { case NODE_TEXCO_OBJECT: { - data = sd->P + sd->dP.dx; + data = svm_node_bump_P_dx(sd); if (node.w == 0) { if (sd->object != OBJECT_NONE) { object_inverse_position_transform(kg, sd, &data); @@ -130,9 +130,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg, Transform tfm = kernel_data.cam.worldtocamera; if (sd->object != OBJECT_NONE) - data = transform_point(&tfm, sd->P + sd->dP.dx); + data = transform_point(&tfm, svm_node_bump_P_dx(sd)); else - data = transform_point(&tfm, sd->P + sd->dP.dx + camera_position(kg)); + data = transform_point(&tfm, svm_node_bump_P_dx(sd) + camera_position(kg)); break; } case NODE_TEXCO_WINDOW: { @@ -140,7 +140,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg, kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) data = camera_world_to_ndc(kg, sd, sd->ray_P); else - data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx); + data = camera_world_to_ndc(kg, sd, svm_node_bump_P_dx(sd)); data.z = 0.0f; break; } @@ -160,7 +160,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg, break; } case NODE_TEXCO_VOLUME_GENERATED: { - data = sd->P + sd->dP.dx; + data = svm_node_bump_P_dx(sd); # ifdef __VOLUME__ if (sd->object != OBJECT_NONE) @@ -191,7 +191,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg, switch (type) { case NODE_TEXCO_OBJECT: { - data = sd->P + sd->dP.dy; + data = svm_node_bump_P_dy(sd); if (node.w == 0) { if (sd->object != OBJECT_NONE) { object_inverse_position_transform(kg, sd, &data); @@ -215,9 +215,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg, Transform tfm = kernel_data.cam.worldtocamera; if (sd->object != OBJECT_NONE) - data = transform_point(&tfm, sd->P + sd->dP.dy); + data = transform_point(&tfm, svm_node_bump_P_dy(sd)); else - data = transform_point(&tfm, sd->P + sd->dP.dy + camera_position(kg)); + data = transform_point(&tfm, svm_node_bump_P_dy(sd) + camera_position(kg)); break; } case NODE_TEXCO_WINDOW: { @@ -225,7 +225,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg, kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) data = camera_world_to_ndc(kg, sd, sd->ray_P); else - data = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy); + data = camera_world_to_ndc(kg, sd, svm_node_bump_P_dy(sd)); data.z = 0.0f; break; } @@ -245,7 +245,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg, break; } case NODE_TEXCO_VOLUME_GENERATED: { - data = sd->P + sd->dP.dy; + data = svm_node_bump_P_dy(sd); # ifdef __VOLUME__ if (sd->object != OBJECT_NONE) diff --git a/intern/cycles/kernel/svm/types.h b/intern/cycles/kernel/svm/types.h index 12d0ec141e6..98dfe6a4375 100644 --- a/intern/cycles/kernel/svm/types.h +++ b/intern/cycles/kernel/svm/types.h @@ -12,7 +12,7 @@ CCL_NAMESPACE_BEGIN /* SVM stack offsets with this value indicate that it's not on the stack */ #define SVM_STACK_INVALID 255 -#define SVM_BUMP_EVAL_STATE_SIZE 9 +#define SVM_BUMP_EVAL_STATE_SIZE 4 /* Nodes */ diff --git a/intern/cycles/kernel/svm/wireframe.h b/intern/cycles/kernel/svm/wireframe.h index e5fe08e5d04..91fadf4cfc4 100644 --- a/intern/cycles/kernel/svm/wireframe.h +++ b/intern/cycles/kernel/svm/wireframe.h @@ -14,6 +14,7 @@ CCL_NAMESPACE_BEGIN ccl_device_inline float wireframe(KernelGlobals kg, ccl_private ShaderData *sd, + const differential3 dP, float size, int pixel_size, ccl_private float3 *P) @@ -46,8 +47,8 @@ ccl_device_inline float wireframe(KernelGlobals kg, if (pixel_size) { // Project the derivatives of P to the viewing plane defined // by I so we have a measure of how big is a pixel at this point - float pixelwidth_x = len(sd->dP.dx - dot(sd->dP.dx, sd->I) * sd->I); - float pixelwidth_y = len(sd->dP.dy - dot(sd->dP.dy, sd->I) * sd->I); + float pixelwidth_x = len(dP.dx - dot(dP.dx, sd->I) * sd->I); + float pixelwidth_y = len(dP.dy - dot(dP.dy, sd->I) * sd->I); // Take the average of both axis' length pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f; } @@ -86,16 +87,17 @@ ccl_device_noinline void svm_node_wireframe(KernelGlobals kg, int pixel_size = (int)use_pixel_size; /* Calculate wireframe */ - float f = wireframe(kg, sd, size, pixel_size, &sd->P); + const differential3 dP = differential_from_compact(sd->Ng, sd->dP); + float f = wireframe(kg, sd, dP, size, pixel_size, &sd->P); /* TODO(sergey): Think of faster way to calculate derivatives. */ if (bump_offset == NODE_BUMP_OFFSET_DX) { - float3 Px = sd->P - sd->dP.dx; - f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len(sd->dP.dx); + float3 Px = sd->P - dP.dx; + f += (f - wireframe(kg, sd, dP, size, pixel_size, &Px)) / len(dP.dx); } else if (bump_offset == NODE_BUMP_OFFSET_DY) { - float3 Py = sd->P - sd->dP.dy; - f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len(sd->dP.dy); + float3 Py = sd->P - dP.dy; + f += (f - wireframe(kg, sd, dP, size, pixel_size, &Py)) / len(dP.dy); } if (stack_valid(out_fac)) diff --git a/intern/cycles/kernel/tables.h b/intern/cycles/kernel/tables.h index c1fdbba3fa7..399eea1e2b1 100644 --- a/intern/cycles/kernel/tables.h +++ b/intern/cycles/kernel/tables.h @@ -63,4 +63,57 @@ ccl_inline_constant float cie_colour_match[][3] = { {0.0001f, 0.0000f, 0.0000f}, {0.0001f, 0.0000f, 0.0000f}, {0.0000f, 0.0000f, 0.0000f} }; +/* + * The direction vectors for the first four dimensions of the Sobol + * sequence, stored with reversed-order bits. + * + * This is used in the Sobol-Burley sampler implementation. We don't + * need more than four dimensions because we achieve higher dimensions + * with padding. They're stored with reversed bits because we need + * them reversed for the fast hash-based Owen scrambling anyway, and + * this avoids doing that at run time. + */ +ccl_inline_constant unsigned int sobol_burley_table[4][32] = { + { + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000, 0x00800000, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + }, + { + 0x00000001, 0x00000003, 0x00000005, 0x0000000f, + 0x00000011, 0x00000033, 0x00000055, 0x000000ff, + 0x00000101, 0x00000303, 0x00000505, 0x00000f0f, + 0x00001111, 0x00003333, 0x00005555, 0x0000ffff, + 0x00010001, 0x00030003, 0x00050005, 0x000f000f, + 0x00110011, 0x00330033, 0x00550055, 0x00ff00ff, + 0x01010101, 0x03030303, 0x05050505, 0x0f0f0f0f, + 0x11111111, 0x33333333, 0x55555555, 0xffffffff, + }, + { + 0x00000001, 0x00000003, 0x00000006, 0x00000009, + 0x00000017, 0x0000003a, 0x00000071, 0x000000a3, + 0x00000116, 0x00000339, 0x00000677, 0x000009aa, + 0x00001601, 0x00003903, 0x00007706, 0x0000aa09, + 0x00010117, 0x0003033a, 0x00060671, 0x000909a3, + 0x00171616, 0x003a3939, 0x00717777, 0x00a3aaaa, + 0x01170001, 0x033a0003, 0x06710006, 0x09a30009, + 0x16160017, 0x3939003a, 0x77770071, 0xaaaa00a3, + }, + { + 0x00000001, 0x00000003, 0x00000004, 0x0000000a, + 0x0000001f, 0x0000002e, 0x00000045, 0x000000c9, + 0x0000011b, 0x000002a4, 0x0000079a, 0x00000b67, + 0x0000101e, 0x0000302d, 0x00004041, 0x0000a0c3, + 0x0001f104, 0x0002e28a, 0x000457df, 0x000c9bae, + 0x0011a105, 0x002a7289, 0x0079e7db, 0x00b6dba4, + 0x0100011a, 0x030002a7, 0x0400079e, 0x0a000b6d, + 0x1f001001, 0x2e003003, 0x45004004, 0xc900a00a, + }, +}; + /* clang-format on */ diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 7762c95275e..f55ace1a227 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -178,6 +178,7 @@ enum PathTraceDimension { enum SamplingPattern { SAMPLING_PATTERN_SOBOL = 0, SAMPLING_PATTERN_PMJ = 1, + SAMPLING_PATTERN_SOBOL_BURLEY = 2, SAMPLING_NUM_PATTERNS, }; @@ -413,9 +414,9 @@ typedef enum CryptomatteType { } CryptomatteType; typedef struct BsdfEval { - float3 diffuse; - float3 glossy; - float3 sum; + Spectrum diffuse; + Spectrum glossy; + Spectrum sum; } BsdfEval; /* Closure Filter */ @@ -709,7 +710,7 @@ typedef struct AttributeMap { * padded to be 16 bytes, while it's only 12 bytes on the GPU. */ #define SHADER_CLOSURE_BASE \ - float3 weight; \ + Spectrum weight; \ ClosureType type; \ float sample_weight; \ float3 N @@ -718,10 +719,9 @@ typedef struct ccl_align(16) ShaderClosure { SHADER_CLOSURE_BASE; -#ifndef __KERNEL_GPU__ - float pad[2]; -#endif - float data[10]; + /* Extra space for closures to store data, somewhat arbitrary but closures + * assert that their size fits. */ + char pad[sizeof(Spectrum) * 2 + sizeof(float) * 4]; } ShaderClosure; @@ -874,10 +874,10 @@ typedef struct ccl_align(16) ShaderData float ray_length; #ifdef __RAY_DIFFERENTIALS__ - /* differential of P. these are orthogonal to Ng, not N */ - differential3 dP; - /* differential of I */ - differential3 dI; + /* Radius of differential of P. */ + float dP; + /* Radius of differential of I. */ + float dI; /* differential of u, v */ differential du; differential dv; @@ -912,12 +912,12 @@ typedef struct ccl_align(16) ShaderData /* Closure data, we store a fixed array of closures */ int num_closure; int num_closure_left; - float3 svm_closure_weight; + Spectrum svm_closure_weight; /* Closure weights summed directly, so we can evaluate * emission and shadow transparency with MAX_CLOSURE 0. */ - float3 closure_emission_background; - float3 closure_transparent_extinction; + Spectrum closure_emission_background; + Spectrum closure_transparent_extinction; /* At the end so we can adjust size in ShaderDataTinyStorage. */ struct ShaderClosure closure[MAX_CLOSURE]; @@ -948,7 +948,7 @@ ShaderDataCausticsStorage; * Used for decoupled direct/indirect light closure storage. */ typedef struct ShaderVolumeClosure { - float3 weight; + Spectrum weight; float sample_weight; float g; } ShaderVolumeClosure; diff --git a/intern/cycles/kernel/util/color.h b/intern/cycles/kernel/util/color.h index c85ef262d88..4983b9048d4 100644 --- a/intern/cycles/kernel/util/color.h +++ b/intern/cycles/kernel/util/color.h @@ -33,4 +33,19 @@ ccl_device float linear_rgb_to_gray(KernelGlobals kg, float3 c) return dot(c, float4_to_float3(kernel_data.film.rgb_to_y)); } +ccl_device_inline Spectrum rgb_to_spectrum(float3 rgb) +{ + return rgb; +} + +ccl_device_inline float3 spectrum_to_rgb(Spectrum s) +{ + return s; +} + +ccl_device float spectrum_to_gray(KernelGlobals kg, Spectrum c) +{ + return linear_rgb_to_gray(kg, spectrum_to_rgb(c)); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/util/differential.h b/intern/cycles/kernel/util/differential.h index 3682e91ea66..aad9bb6bb22 100644 --- a/intern/cycles/kernel/util/differential.h +++ b/intern/cycles/kernel/util/differential.h @@ -101,53 +101,59 @@ ccl_device differential3 differential3_zero() return d; } -/* Compact ray differentials that are just a scale to reduce memory usage and - * access cost in GPU. +/* Compact ray differentials that are just a radius to reduce memory usage and access cost + * on GPUs, basically cone tracing. * - * See above for more accurate reference implementations. - * - * TODO: also store the more compact version in ShaderData and recompute where - * needed? */ + * See above for more accurate reference implementations of ray differentials. */ ccl_device_forceinline float differential_zero_compact() { return 0.0f; } -ccl_device_forceinline float differential_make_compact(const differential3 D) +ccl_device_forceinline float differential_make_compact(const float dD) { - return 0.5f * (len(D.dx) + len(D.dy)); + return dD; } -ccl_device_forceinline void differential_transfer_compact(ccl_private differential3 *surface_dP, - const float ray_dP, - const float3 /* ray_D */, - const float ray_dD, - const float3 surface_Ng, - const float ray_t) +ccl_device_forceinline float differential_make_compact(const differential3 dD) { - /* ray differential transfer through homogeneous medium, to - * compute dPdx/dy at a shading point from the incoming ray */ - float scale = ray_dP + ray_t * ray_dD; + return 0.5f * (len(dD.dx) + len(dD.dy)); +} - float3 dx, dy; - make_orthonormals(surface_Ng, &dx, &dy); - surface_dP->dx = dx * scale; - surface_dP->dy = dy * scale; +ccl_device_forceinline float differential_incoming_compact(const float dD) +{ + return dD; } -ccl_device_forceinline void differential_incoming_compact(ccl_private differential3 *dI, - const float3 D, - const float dD) +ccl_device_forceinline float differential_transfer_compact(const float ray_dP, + const float3 /* ray_D */, + const float ray_dD, + const float ray_t) { - /* compute dIdx/dy at a shading point, we just need to negate the - * differential of the ray direction */ + return ray_dP + ray_t * ray_dD; +} +ccl_device_forceinline differential3 differential_from_compact(const float3 D, const float dD) +{ float3 dx, dy; make_orthonormals(D, &dx, &dy); - dI->dx = dD * dx; - dI->dy = dD * dy; + differential3 d; + d.dx = dD * dx; + d.dy = dD * dy; + return d; +} + +ccl_device void differential_dudv_compact(ccl_private differential *du, + ccl_private differential *dv, + float3 dPdu, + float3 dPdv, + float dP, + float3 Ng) +{ + /* TODO: can we speed this up? */ + differential_dudv(du, dv, dPdu, dPdv, differential_from_compact(Ng, dP), Ng); } CCL_NAMESPACE_END diff --git a/intern/cycles/scene/CMakeLists.txt b/intern/cycles/scene/CMakeLists.txt index 4904bf247ba..a30f408f207 100644 --- a/intern/cycles/scene/CMakeLists.txt +++ b/intern/cycles/scene/CMakeLists.txt @@ -148,6 +148,4 @@ endif() include_directories(${INC}) include_directories(SYSTEM ${INC_SYS}) -add_definitions(${GL_DEFINITIONS}) - cycles_add_library(cycles_scene "${LIB}" ${SRC} ${SRC_HEADERS}) diff --git a/intern/cycles/scene/camera.cpp b/intern/cycles/scene/camera.cpp index eec269ab542..d9e574873bd 100644 --- a/intern/cycles/scene/camera.cpp +++ b/intern/cycles/scene/camera.cpp @@ -772,10 +772,7 @@ float Camera::world_to_raster_size(float3 P) #endif /* TODO: would it help to use more accurate differentials here? */ - differential3 dP; - differential_transfer_compact(&dP, ray.dP, ray.D, ray.dD, ray.D, dist); - - return max(len(dP.dx), len(dP.dy)); + return differential_transfer_compact(ray.dP, ray.D, ray.dD, dist); } return res; diff --git a/intern/cycles/scene/image_oiio.cpp b/intern/cycles/scene/image_oiio.cpp index 67d73759dd9..8792393e5a1 100644 --- a/intern/cycles/scene/image_oiio.cpp +++ b/intern/cycles/scene/image_oiio.cpp @@ -185,8 +185,7 @@ bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata, /* Load without automatic OIIO alpha conversion, we do it ourselves. OIIO * will associate alpha in the 8bit buffer for PNGs, which leads to too - * much precision loss when we load it as half float to do a color-space - * transform. */ + * much precision loss when we load it as half float to do a color-space transform. */ config.attribute("oiio:UnassociatedAlpha", 1); if (!in->open(filepath.string(), spec, config)) { diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp index aa11004fb48..58daf417ab0 100644 --- a/intern/cycles/scene/integrator.cpp +++ b/intern/cycles/scene/integrator.cpp @@ -89,6 +89,7 @@ NODE_DEFINE(Integrator) static NodeEnum sampling_pattern_enum; sampling_pattern_enum.insert("sobol", SAMPLING_PATTERN_SOBOL); sampling_pattern_enum.insert("pmj", SAMPLING_PATTERN_PMJ); + sampling_pattern_enum.insert("sobol_burley", SAMPLING_PATTERN_SOBOL_BURLEY); SOCKET_ENUM(sampling_pattern, "Sampling Pattern", sampling_pattern_enum, SAMPLING_PATTERN_SOBOL); SOCKET_FLOAT(scrambling_distance, "Scrambling Distance", 1.0f); @@ -260,7 +261,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene dscene->sample_pattern_lut.copy_to_device(); } - else { + else if (kintegrator->sampling_pattern == SAMPLING_PATTERN_PMJ) { constexpr int sequence_size = NUM_PMJ_SAMPLES; constexpr int num_sequences = NUM_PMJ_PATTERNS; float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size * diff --git a/intern/cycles/session/CMakeLists.txt b/intern/cycles/session/CMakeLists.txt index 6e4e6af6e71..4f3a0a99ee1 100644 --- a/intern/cycles/session/CMakeLists.txt +++ b/intern/cycles/session/CMakeLists.txt @@ -32,6 +32,4 @@ set(LIB include_directories(${INC}) include_directories(SYSTEM ${INC_SYS}) -add_definitions(${GL_DEFINITIONS}) - cycles_add_library(cycles_session "${LIB}" ${SRC} ${SRC_HEADERS}) diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp index c94b53535a7..e5df22211e7 100644 --- a/intern/cycles/session/session.cpp +++ b/intern/cycles/session/session.cpp @@ -503,7 +503,9 @@ void Session::do_delayed_reset() if (!params.background) { progress.set_start_time(); } + const double time_limit = params.time_limit * ((double)tile_manager_.get_num_tiles()); progress.set_render_start_time(); + progress.set_time_limit(time_limit); } void Session::reset(const SessionParams &session_params, const BufferParams &buffer_params) @@ -598,7 +600,8 @@ double Session::get_estimated_remaining_time() const progress.get_time(total_time, render_time); double remaining = (1.0 - (double)completed) * (render_time / (double)completed); - const double time_limit = render_scheduler_.get_time_limit(); + const double time_limit = render_scheduler_.get_time_limit() * + ((double)tile_manager_.get_num_tiles()); if (time_limit != 0.0) { remaining = min(remaining, max(time_limit - render_time, 0.0)); } diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt index f3fc7739f66..997d574a3b0 100644 --- a/intern/cycles/util/CMakeLists.txt +++ b/intern/cycles/util/CMakeLists.txt @@ -3,7 +3,6 @@ set(INC .. - ../../glew-mx ) set(INC_SYS @@ -118,6 +117,7 @@ set(SRC_HEADERS types_int3_impl.h types_int4.h types_int4_impl.h + types_spectrum.h types_uchar2.h types_uchar2_impl.h types_uchar3.h @@ -131,8 +131,6 @@ set(SRC_HEADERS types_uint4.h types_uint4_impl.h types_ushort4.h - types_vector3.h - types_vector3_impl.h unique_ptr.h vector.h version.h @@ -150,6 +148,4 @@ endif() include_directories(${INC}) include_directories(SYSTEM ${INC_SYS}) -add_definitions(${GL_DEFINITIONS}) - cycles_add_library(cycles_util "${LIB}" ${SRC} ${SRC_HEADERS}) diff --git a/intern/cycles/util/debug.cpp b/intern/cycles/util/debug.cpp index faa54a92c24..8210e21f951 100644 --- a/intern/cycles/util/debug.cpp +++ b/intern/cycles/util/debug.cpp @@ -13,7 +13,6 @@ CCL_NAMESPACE_BEGIN DebugFlags::CPU::CPU() - : avx2(true), avx(true), sse41(true), sse3(true), sse2(true), bvh_layout(BVH_LAYOUT_AUTO) { reset(); } @@ -41,17 +40,17 @@ void DebugFlags::CPU::reset() bvh_layout = BVH_LAYOUT_AUTO; } -DebugFlags::CUDA::CUDA() : adaptive_compile(false) +DebugFlags::CUDA::CUDA() { reset(); } -DebugFlags::HIP::HIP() : adaptive_compile(false) +DebugFlags::HIP::HIP() { reset(); } -DebugFlags::Metal::Metal() : adaptive_compile(false) +DebugFlags::Metal::Metal() { reset(); } @@ -84,14 +83,13 @@ void DebugFlags::OptiX::reset() use_debug = false; } -DebugFlags::DebugFlags() : viewport_static_bvh(false), running_inside_blender(false) +DebugFlags::DebugFlags() { /* Nothing for now. */ } void DebugFlags::reset() { - viewport_static_bvh = false; cpu.reset(); cuda.reset(); optix.reset(); diff --git a/intern/cycles/util/debug.h b/intern/cycles/util/debug.h index 3565fdea17f..ab200649f59 100644 --- a/intern/cycles/util/debug.h +++ b/intern/cycles/util/debug.h @@ -17,11 +17,6 @@ CCL_NAMESPACE_BEGIN */ class DebugFlags { public: - /* Use static BVH in viewport, to match final render exactly. */ - bool viewport_static_bvh; - - bool running_inside_blender; - /* Descriptor of CPU feature-set to be used. */ struct CPU { CPU(); @@ -30,11 +25,11 @@ class DebugFlags { void reset(); /* Flags describing which instructions sets are allowed for use. */ - bool avx2; - bool avx; - bool sse41; - bool sse3; - bool sse2; + bool avx2 = true; + bool avx = true; + bool sse41 = true; + bool sse3 = true; + bool sse2 = true; /* Check functions to see whether instructions up to the given one * are allowed for use. @@ -65,7 +60,7 @@ class DebugFlags { * By default the fastest will be used. For debugging the BVH used by other * CPUs and GPUs can be selected here instead. */ - BVHLayout bvh_layout; + BVHLayout bvh_layout = BVH_LAYOUT_AUTO; }; /* Descriptor of CUDA feature-set to be used. */ @@ -77,7 +72,7 @@ class DebugFlags { /* Whether adaptive feature based runtime compile is enabled or not. * Requires the CUDA Toolkit and only works on Linux at the moment. */ - bool adaptive_compile; + bool adaptive_compile = false; }; /* Descriptor of HIP feature-set to be used. */ @@ -88,7 +83,7 @@ class DebugFlags { void reset(); /* Whether adaptive feature based runtime compile is enabled or not. */ - bool adaptive_compile; + bool adaptive_compile = false; }; /* Descriptor of OptiX feature-set to be used. */ @@ -100,7 +95,7 @@ class DebugFlags { /* Load OptiX module with debug capabilities. Will lower logging verbosity level, enable * validations, and lower optimization level. */ - bool use_debug; + bool use_debug = false; }; /* Descriptor of Metal feature-set to be used. */ @@ -111,7 +106,7 @@ class DebugFlags { void reset(); /* Whether adaptive feature based runtime compile is enabled or not. */ - bool adaptive_compile; + bool adaptive_compile = false; }; /* Get instance of debug flags registry. */ @@ -142,15 +137,9 @@ class DebugFlags { private: DebugFlags(); -#if (__cplusplus > 199711L) public: explicit DebugFlags(DebugFlags const & /*other*/) = delete; void operator=(DebugFlags const & /*other*/) = delete; -#else - private: - explicit DebugFlags(DebugFlags const & /*other*/); - void operator=(DebugFlags const & /*other*/); -#endif }; typedef DebugFlags &DebugFlagsRef; diff --git a/intern/cycles/util/defines.h b/intern/cycles/util/defines.h index 56a41a1dc45..1969529eff0 100644 --- a/intern/cycles/util/defines.h +++ b/intern/cycles/util/defines.h @@ -96,4 +96,7 @@ # define util_assert(statement) #endif +#define CONCAT_HELPER(a, ...) a##__VA_ARGS__ +#define CONCAT(a, ...) CONCAT_HELPER(a, __VA_ARGS__) + #endif /* __UTIL_DEFINES_H__ */ diff --git a/intern/cycles/util/hash.h b/intern/cycles/util/hash.h index 081b33025d8..61705276a90 100644 --- a/intern/cycles/util/hash.h +++ b/intern/cycles/util/hash.h @@ -8,6 +8,23 @@ CCL_NAMESPACE_BEGIN +/* [0, uint_max] -> [0.0, 1.0) */ +ccl_device_forceinline float uint_to_float_excl(uint n) +{ + // Note: we divide by 4294967808 instead of 2^32 because the latter + // leads to a [0.0, 1.0] mapping instead of [0.0, 1.0) due to floating + // point rounding error. 4294967808 unfortunately leaves (precisely) + // one unused ulp between the max number this outputs and 1.0, but + // that's the best you can do with this construction. + return (float)n * (1.0f / 4294967808.0f); +} + +/* [0, uint_max] -> [0.0, 1.0] */ +ccl_device_forceinline float uint_to_float_incl(uint n) +{ + return (float)n * (1.0f / (float)0xFFFFFFFFu); +} + /* ***** Jenkins Lookup3 Hash Functions ***** */ /* Source: http://burtleburtle.net/bob/c/lookup3.c */ @@ -116,22 +133,22 @@ ccl_device_inline uint hash_uint4(uint kx, uint ky, uint kz, uint kw) ccl_device_inline float hash_uint_to_float(uint kx) { - return (float)hash_uint(kx) / (float)0xFFFFFFFFu; + return uint_to_float_incl(hash_uint(kx)); } ccl_device_inline float hash_uint2_to_float(uint kx, uint ky) { - return (float)hash_uint2(kx, ky) / (float)0xFFFFFFFFu; + return uint_to_float_incl(hash_uint2(kx, ky)); } ccl_device_inline float hash_uint3_to_float(uint kx, uint ky, uint kz) { - return (float)hash_uint3(kx, ky, kz) / (float)0xFFFFFFFFu; + return uint_to_float_incl(hash_uint3(kx, ky, kz)); } ccl_device_inline float hash_uint4_to_float(uint kx, uint ky, uint kz, uint kw) { - return (float)hash_uint4(kx, ky, kz, kw) / (float)0xFFFFFFFFu; + return uint_to_float_incl(hash_uint4(kx, ky, kz, kw)); } /* Hashing float or float[234] into a float in the range [0, 1]. */ @@ -359,6 +376,101 @@ ccl_device_inline avxi hash_avxi4(avxi kx, avxi ky, avxi kz, avxi kw) #endif +/* ***** Hash Prospector Hash Functions ***** + * + * These are based on the high-quality 32-bit hash/mixings functions from + * https://github.com/skeeto/hash-prospector + */ + +ccl_device_inline uint hash_hp_uint(uint i) +{ + // The actual mixing function from Hash Prospector. + i ^= i >> 16; + i *= 0x21f0aaad; + i ^= i >> 15; + i *= 0xd35a2d97; + i ^= i >> 15; + + // The xor is just to make input zero not map to output zero. + // The number is randomly selected and isn't special. + return i ^ 0xe6fe3beb; +} + +/* Seedable version of hash_hp_uint() above. */ +ccl_device_inline uint hash_hp_seeded_uint(uint i, uint seed) +{ + // Manipulate the seed so it doesn't interact poorly with n when they + // are both e.g. incrementing. This isn't fool-proof, but is good + // enough for practical use. + seed ^= seed << 19; + + return hash_hp_uint(i ^ seed); +} + +/* Outputs [0.0, 1.0]. */ +ccl_device_inline float hash_hp_seeded_float(uint i, uint seed) +{ + return uint_to_float_incl(hash_hp_seeded_uint(i, seed)); +} + +/* ***** CMJ Hash Functions ***** + * + * These are based on one of the hash functions in the paper + * "Correlated Multi-Jittered Sampling" by Andrew Kensler, 2013. + * + * These are here for backwards-compatibility, and can be replaced + * by the Hash Prospector hashes above at some point. + * See https://developer.blender.org/D15679#426304 + */ + +ccl_device_inline uint hash_cmj_seeded_uint(uint i, uint seed) +{ + i ^= seed; + i ^= i >> 17; + i ^= i >> 10; + i *= 0xb36534e5; + i ^= i >> 12; + i ^= i >> 21; + i *= 0x93fc4795; + i ^= 0xdf6e307f; + i ^= i >> 17; + i *= 1 | seed >> 18; + + return i; +} + +/* Outputs [0.0, 1.0]. */ +ccl_device_inline float hash_cmj_seeded_float(uint i, uint seed) +{ + return uint_to_float_excl(hash_cmj_seeded_uint(i, seed)); +} + +/* ***** Modified Wang Hash Functions ***** + * + * These are based on a bespoke modified version of the Wang hash, and + * can serve as a faster hash when quality isn't critical. + * + * The original Wang hash is documented here: + * https://www.burtleburtle.net/bob/hash/integer.html + */ + +ccl_device_inline uint hash_wang_seeded_uint(uint i, uint seed) +{ + i = (i ^ 61) ^ seed; + i += i << 3; + i ^= i >> 4; + i *= 0x27d4eb2d; + return i; +} + +/* Outputs [0.0, 1.0]. */ +ccl_device_inline float hash_wang_seeded_float(uint i, uint seed) +{ + return uint_to_float_incl(hash_wang_seeded_uint(i, seed)); +} + +/* ********** */ + #ifndef __KERNEL_GPU__ static inline uint hash_string(const char *str) { diff --git a/intern/cycles/util/math.h b/intern/cycles/util/math.h index f6400cb879f..0585dcc8ad5 100644 --- a/intern/cycles/util/math.h +++ b/intern/cycles/util/math.h @@ -595,26 +595,26 @@ ccl_device_inline void make_orthonormals(const float3 N, /* Color division */ -ccl_device_inline float3 safe_invert_color(float3 a) +ccl_device_inline Spectrum safe_invert_color(Spectrum a) { - float x, y, z; - - x = (a.x != 0.0f) ? 1.0f / a.x : 0.0f; - y = (a.y != 0.0f) ? 1.0f / a.y : 0.0f; - z = (a.z != 0.0f) ? 1.0f / a.z : 0.0f; + FOREACH_SPECTRUM_CHANNEL (i) { + GET_SPECTRUM_CHANNEL(a, i) = (GET_SPECTRUM_CHANNEL(a, i) != 0.0f) ? + 1.0f / GET_SPECTRUM_CHANNEL(a, i) : + 0.0f; + } - return make_float3(x, y, z); + return a; } -ccl_device_inline float3 safe_divide_color(float3 a, float3 b) +ccl_device_inline Spectrum safe_divide_color(Spectrum a, Spectrum b) { - float x, y, z; - - x = (b.x != 0.0f) ? a.x / b.x : 0.0f; - y = (b.y != 0.0f) ? a.y / b.y : 0.0f; - z = (b.z != 0.0f) ? a.z / b.z : 0.0f; + FOREACH_SPECTRUM_CHANNEL (i) { + GET_SPECTRUM_CHANNEL(a, i) = (GET_SPECTRUM_CHANNEL(b, i) != 0.0f) ? + GET_SPECTRUM_CHANNEL(a, i) / GET_SPECTRUM_CHANNEL(b, i) : + 0.0f; + } - return make_float3(x, y, z); + return a; } ccl_device_inline float3 safe_divide_even_color(float3 a, float3 b) diff --git a/intern/cycles/util/opengl.h b/intern/cycles/util/opengl.h index 090deb861c4..fefee4ec022 100644 --- a/intern/cycles/util/opengl.h +++ b/intern/cycles/util/opengl.h @@ -7,6 +7,6 @@ /* OpenGL header includes, used everywhere we use OpenGL, to deal with * platform differences in one central place. */ -#include <GL/glew.h> +#include <epoxy/gl.h> #endif /* __UTIL_OPENGL_H__ */ diff --git a/intern/cycles/util/progress.h b/intern/cycles/util/progress.h index 37eafd57491..586979d2021 100644 --- a/intern/cycles/util/progress.h +++ b/intern/cycles/util/progress.h @@ -28,6 +28,7 @@ class Progress { denoised_tiles = 0; start_time = time_dt(); render_start_time = time_dt(); + time_limit = 0.0; end_time = 0.0; status = "Initializing"; substatus = ""; @@ -68,6 +69,7 @@ class Progress { denoised_tiles = 0; start_time = time_dt(); render_start_time = time_dt(); + time_limit = 0.0; end_time = 0.0; status = "Initializing"; substatus = ""; @@ -145,6 +147,13 @@ class Progress { render_start_time = time_dt(); } + void set_time_limit(double time_limit_) + { + thread_scoped_lock lock(progress_mutex); + + time_limit = time_limit_; + } + void add_skip_time(const scoped_timer &start_timer, bool only_render) { double skip_time = time_dt() - start_timer.get_start(); @@ -191,8 +200,13 @@ class Progress { { thread_scoped_lock lock(progress_mutex); - if (total_pixel_samples > 0) { - return ((double)pixel_samples) / (double)total_pixel_samples; + if (pixel_samples > 0) { + double progress_percent = (double)pixel_samples / (double)total_pixel_samples; + if (time_limit != 0.0) { + double time_since_render_start = time_dt() - render_start_time; + progress_percent = max(progress_percent, time_since_render_start / time_limit); + } + return min(1.0, progress_percent); } return 0.0; } @@ -335,7 +349,7 @@ class Progress { * in which case the current_tile_sample is displayed. */ int rendered_tiles, denoised_tiles; - double start_time, render_start_time; + double start_time, render_start_time, time_limit; /* End time written when render is done, so it doesn't keep increasing on redraws. */ double end_time; diff --git a/intern/cycles/util/types.h b/intern/cycles/util/types.h index 031c2f7c4c1..1ab6f76f9bc 100644 --- a/intern/cycles/util/types.h +++ b/intern/cycles/util/types.h @@ -12,6 +12,7 @@ #if !defined(__KERNEL_GPU__) # include <stdint.h> +# include <stdio.h> #endif #include "util/defines.h" @@ -70,6 +71,24 @@ ccl_device_inline bool is_power_of_two(size_t x) CCL_NAMESPACE_END +/* Device side printf only tested on CUDA, may work on more GPU devices. */ +#if !defined(__KERNEL_GPU__) || defined(__KERNEL_CUDA__) +# define __KERNEL_PRINTF__ +#endif + +ccl_device_inline void print_float(ccl_private const char *label, const float a) +{ +#ifdef __KERNEL_PRINTF__ + printf("%s: %.8f\n", label, (double)a); +#endif +} + +/* Most GPU APIs matching native vector types, so we only need to implement them for + * CPU and oneAPI. */ +#if defined(__KERNEL_GPU__) && !defined(__KERNEL_ONEAPI__) +# define __KERNEL_NATIVE_VECTOR_TYPES__ +#endif + /* Vectorized types declaration. */ #include "util/types_uchar2.h" #include "util/types_uchar3.h" @@ -90,7 +109,7 @@ CCL_NAMESPACE_END #include "util/types_float4.h" #include "util/types_float8.h" -#include "util/types_vector3.h" +#include "util/types_spectrum.h" /* Vectorized types implementation. */ #include "util/types_uchar2_impl.h" @@ -110,8 +129,6 @@ CCL_NAMESPACE_END #include "util/types_float4_impl.h" #include "util/types_float8_impl.h" -#include "util/types_vector3_impl.h" - /* SSE types. */ #ifndef __KERNEL_GPU__ # include "util/sseb.h" diff --git a/intern/cycles/util/types_float2.h b/intern/cycles/util/types_float2.h index 07b9ec0986b..ea510ef832c 100644 --- a/intern/cycles/util/types_float2.h +++ b/intern/cycles/util/types_float2.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_FLOAT2_H__ -#define __UTIL_TYPES_FLOAT2_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,18 +9,19 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct float2 { float x, y; +# ifndef __KERNEL_GPU__ __forceinline float operator[](int i) const; __forceinline float &operator[](int i); +# endif }; ccl_device_inline float2 make_float2(float x, float y); -ccl_device_inline void print_float2(const char *label, const float2 &a); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ -CCL_NAMESPACE_END +ccl_device_inline void print_float2(ccl_private const char *label, const float2 a); -#endif /* __UTIL_TYPES_FLOAT2_H__ */ +CCL_NAMESPACE_END diff --git a/intern/cycles/util/types_float2_impl.h b/intern/cycles/util/types_float2_impl.h index 45fc90c52bd..7ba7dee2e3a 100644 --- a/intern/cycles/util/types_float2_impl.h +++ b/intern/cycles/util/types_float2_impl.h @@ -1,20 +1,16 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_FLOAT2_IMPL_H__ -#define __UTIL_TYPES_FLOAT2_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." #endif -#ifndef __KERNEL_GPU__ -# include <cstdio> -#endif - CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ +# ifndef __KERNEL_GPU__ __forceinline float float2::operator[](int i) const { util_assert(i >= 0); @@ -28,19 +24,20 @@ __forceinline float &float2::operator[](int i) util_assert(i < 2); return *(&x + i); } +# endif ccl_device_inline float2 make_float2(float x, float y) { float2 a = {x, y}; return a; } +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ -ccl_device_inline void print_float2(const char *label, const float2 &a) +ccl_device_inline void print_float2(ccl_private const char *label, const float2 a) { +#ifdef __KERNEL_PRINTF__ printf("%s: %.8f %.8f\n", label, (double)a.x, (double)a.y); +#endif } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_FLOAT2_IMPL_H__ */ diff --git a/intern/cycles/util/types_float3.h b/intern/cycles/util/types_float3.h index c7900acaa69..87c6b1d3654 100644 --- a/intern/cycles/util/types_float3.h +++ b/intern/cycles/util/types_float3.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_FLOAT3_H__ -#define __UTIL_TYPES_FLOAT3_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,17 +9,28 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct ccl_try_align(16) float3 { -# ifdef __KERNEL_SSE__ +# ifdef __KERNEL_GPU__ + /* Compact structure for GPU. */ + float x, y, z; +# else + /* SIMD aligned structure for CPU. */ +# ifdef __KERNEL_SSE__ union { __m128 m128; struct { float x, y, z, w; }; }; +# else + float x, y, z, w; +# endif +# endif +# ifdef __KERNEL_SSE__ + /* Convenient constructors and operators for SIMD, otherwise default is enough. */ __forceinline float3(); __forceinline float3(const float3 &a); __forceinline explicit float3(const __m128 &a); @@ -29,18 +39,19 @@ struct ccl_try_align(16) float3 __forceinline operator __m128 &(); __forceinline float3 &operator=(const float3 &a); -# else /* __KERNEL_SSE__ */ - float x, y, z, w; -# endif /* __KERNEL_SSE__ */ +# endif +# ifndef __KERNEL_GPU__ __forceinline float operator[](int i) const; __forceinline float &operator[](int i); +# endif }; -ccl_device_inline float3 make_float3(float f); ccl_device_inline float3 make_float3(float x, float y, float z); -ccl_device_inline void print_float3(const char *label, const float3 &a); -#endif /* !defined(__KERNEL_GPU__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ + +ccl_device_inline float3 make_float3(float f); +ccl_device_inline void print_float3(ccl_private const char *label, const float3 a); /* Smaller float3 for storage. For math operations this must be converted to float3, so that on the * CPU SIMD instructions can be used. */ @@ -78,5 +89,3 @@ struct packed_float3 { static_assert(sizeof(packed_float3) == 12, "packed_float3 expected to be exactly 12 bytes"); CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_FLOAT3_H__ */ diff --git a/intern/cycles/util/types_float3_impl.h b/intern/cycles/util/types_float3_impl.h index 2e6e864c8ea..da76ab2ab2a 100644 --- a/intern/cycles/util/types_float3_impl.h +++ b/intern/cycles/util/types_float3_impl.h @@ -1,20 +1,15 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_FLOAT3_IMPL_H__ -#define __UTIL_TYPES_FLOAT3_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." #endif -#ifndef __KERNEL_GPU__ -# include <cstdio> -#endif - CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ # ifdef __KERNEL_SSE__ __forceinline float3::float3() { @@ -45,6 +40,7 @@ __forceinline float3 &float3::operator=(const float3 &a) } # endif /* __KERNEL_SSE__ */ +# ifndef __KERNEL_GPU__ __forceinline float float3::operator[](int i) const { util_assert(i >= 0); @@ -58,33 +54,37 @@ __forceinline float &float3::operator[](int i) util_assert(i < 3); return *(&x + i); } +# endif -ccl_device_inline float3 make_float3(float f) +ccl_device_inline float3 make_float3(float x, float y, float z) { -# ifdef __KERNEL_SSE__ - float3 a(_mm_set1_ps(f)); +# if defined(__KERNEL_GPU__) + return {x, y, z}; +# elif defined(__KERNEL_SSE__) + return float3(_mm_set_ps(0.0f, z, y, x)); # else - float3 a = {f, f, f, f}; + return {x, y, z, 0.0f}; # endif - return a; } -ccl_device_inline float3 make_float3(float x, float y, float z) +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ + +ccl_device_inline float3 make_float3(float f) { -# ifdef __KERNEL_SSE__ - float3 a(_mm_set_ps(0.0f, z, y, x)); -# else - float3 a = {x, y, z, 0.0f}; -# endif - return a; +#if defined(__KERNEL_GPU__) + return make_float3(f, f, f); +#elif defined(__KERNEL_SSE__) + return float3(_mm_set1_ps(f)); +#else + return {f, f, f, f}; +#endif } -ccl_device_inline void print_float3(const char *label, const float3 &a) +ccl_device_inline void print_float3(ccl_private const char *label, const float3 a) { +#ifdef __KERNEL_PRINTF__ printf("%s: %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z); +#endif } -#endif /* !defined(__KERNEL_GPU__) */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_FLOAT3_IMPL_H__ */ diff --git a/intern/cycles/util/types_float4.h b/intern/cycles/util/types_float4.h index 27453bf39e4..a347cfce9a1 100644 --- a/intern/cycles/util/types_float4.h +++ b/intern/cycles/util/types_float4.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_FLOAT4_H__ -#define __UTIL_TYPES_FLOAT4_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,7 +9,7 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct int4; struct ccl_try_align(16) float4 @@ -35,16 +34,17 @@ struct ccl_try_align(16) float4 float x, y, z, w; # endif /* __KERNEL_SSE__ */ +# ifndef __KERNEL_GPU__ __forceinline float operator[](int i) const; __forceinline float &operator[](int i); +# endif }; -ccl_device_inline float4 make_float4(float f); ccl_device_inline float4 make_float4(float x, float y, float z, float w); -ccl_device_inline float4 make_float4(const int4 &i); -ccl_device_inline void print_float4(const char *label, const float4 &a); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ -CCL_NAMESPACE_END +ccl_device_inline float4 make_float4(float f); +ccl_device_inline float4 make_float4(const int4 i); +ccl_device_inline void print_float4(ccl_private const char *label, const float4 a); -#endif /* __UTIL_TYPES_FLOAT4_H__ */ +CCL_NAMESPACE_END diff --git a/intern/cycles/util/types_float4_impl.h b/intern/cycles/util/types_float4_impl.h index d7858f744e3..420d9316926 100644 --- a/intern/cycles/util/types_float4_impl.h +++ b/intern/cycles/util/types_float4_impl.h @@ -1,20 +1,15 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_FLOAT4_IMPL_H__ -#define __UTIL_TYPES_FLOAT4_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." #endif -#ifndef __KERNEL_GPU__ -# include <cstdio> -#endif - CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ # ifdef __KERNEL_SSE__ __forceinline float4::float4() { @@ -41,6 +36,7 @@ __forceinline float4 &float4::operator=(const float4 &a) } # endif /* __KERNEL_SSE__ */ +# ifndef __KERNEL_GPU__ __forceinline float float4::operator[](int i) const { util_assert(i >= 0); @@ -54,43 +50,42 @@ __forceinline float &float4::operator[](int i) util_assert(i < 4); return *(&x + i); } +# endif -ccl_device_inline float4 make_float4(float f) +ccl_device_inline float4 make_float4(float x, float y, float z, float w) { # ifdef __KERNEL_SSE__ - float4 a(_mm_set1_ps(f)); + return float4(_mm_set_ps(w, z, y, x)); # else - float4 a = {f, f, f, f}; + return {x, y, z, w}; # endif - return a; } -ccl_device_inline float4 make_float4(float x, float y, float z, float w) +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ + +ccl_device_inline float4 make_float4(float f) { -# ifdef __KERNEL_SSE__ - float4 a(_mm_set_ps(w, z, y, x)); -# else - float4 a = {x, y, z, w}; -# endif - return a; +#ifdef __KERNEL_SSE__ + return float4(_mm_set1_ps(f)); +#else + return make_float4(f, f, f, f); +#endif } -ccl_device_inline float4 make_float4(const int4 &i) +ccl_device_inline float4 make_float4(const int4 i) { -# ifdef __KERNEL_SSE__ - float4 a(_mm_cvtepi32_ps(i.m128)); -# else - float4 a = {(float)i.x, (float)i.y, (float)i.z, (float)i.w}; -# endif - return a; +#ifdef __KERNEL_SSE__ + return float4(_mm_cvtepi32_ps(i.m128)); +#else + return make_float4((float)i.x, (float)i.y, (float)i.z, (float)i.w); +#endif } -ccl_device_inline void print_float4(const char *label, const float4 &a) +ccl_device_inline void print_float4(ccl_private const char *label, const float4 a) { +#ifdef __KERNEL_PRINTF__ printf("%s: %.8f %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z, (double)a.w); +#endif } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_FLOAT4_IMPL_H__ */ diff --git a/intern/cycles/util/types_float8.h b/intern/cycles/util/types_float8.h index bb9798932ac..29fd632f08e 100644 --- a/intern/cycles/util/types_float8.h +++ b/intern/cycles/util/types_float8.h @@ -2,8 +2,7 @@ * Original code Copyright 2017, Intel Corporation * Modifications Copyright 2018-2022 Blender Foundation. */ -#ifndef __UTIL_TYPES_FLOAT8_H__ -#define __UTIL_TYPES_FLOAT8_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -12,7 +11,7 @@ CCL_NAMESPACE_BEGIN /* float8 is a reserved type in Metal that has not been implemented. For - * that reason this is named float8_t. */ + * that reason this is named float8_t and not using native vector types. */ #ifdef __KERNEL_GPU__ struct float8_t @@ -52,5 +51,3 @@ ccl_device_inline float8_t make_float8_t(float a, float b, float c, float d, float e, float f, float g, float h); CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_FLOAT8_H__ */ diff --git a/intern/cycles/util/types_float8_impl.h b/intern/cycles/util/types_float8_impl.h index 2ab464a791b..e8576cdaf70 100644 --- a/intern/cycles/util/types_float8_impl.h +++ b/intern/cycles/util/types_float8_impl.h @@ -2,17 +2,12 @@ * Original code Copyright 2017, Intel Corporation * Modifications Copyright 2018-2022 Blender Foundation. */ -#ifndef __UTIL_TYPES_FLOAT8_IMPL_H__ -#define __UTIL_TYPES_FLOAT8_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." #endif -#ifndef __KERNEL_GPU__ -# include <cstdio> -#endif - CCL_NAMESPACE_BEGIN #ifdef __KERNEL_AVX2__ @@ -83,5 +78,3 @@ make_float8_t(float a, float b, float c, float d, float e, float f, float g, flo } CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_FLOAT8_IMPL_H__ */ diff --git a/intern/cycles/util/types_int2.h b/intern/cycles/util/types_int2.h index bf69cddc653..604713dffcd 100644 --- a/intern/cycles/util/types_int2.h +++ b/intern/cycles/util/types_int2.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_INT2_H__ -#define __UTIL_TYPES_INT2_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,17 +9,17 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct int2 { int x, y; +# ifndef __KERNEL_GPU__ __forceinline int operator[](int i) const; __forceinline int &operator[](int i); +# endif }; ccl_device_inline int2 make_int2(int x, int y); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_INT2_H__ */ diff --git a/intern/cycles/util/types_int2_impl.h b/intern/cycles/util/types_int2_impl.h index 7bdc77369ee..f48c6f46729 100644 --- a/intern/cycles/util/types_int2_impl.h +++ b/intern/cycles/util/types_int2_impl.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_INT2_IMPL_H__ -#define __UTIL_TYPES_INT2_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,7 +9,8 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ +# ifndef __KERNEL_GPU__ int int2::operator[](int i) const { util_assert(i >= 0); @@ -24,14 +24,13 @@ int &int2::operator[](int i) util_assert(i < 2); return *(&x + i); } +# endif ccl_device_inline int2 make_int2(int x, int y) { int2 a = {x, y}; return a; } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_INT2_IMPL_H__ */ diff --git a/intern/cycles/util/types_int3.h b/intern/cycles/util/types_int3.h index f88ff22ac35..e059ddd3660 100644 --- a/intern/cycles/util/types_int3.h +++ b/intern/cycles/util/types_int3.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_INT3_H__ -#define __UTIL_TYPES_INT3_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,10 +9,15 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct ccl_try_align(16) int3 { -# ifdef __KERNEL_SSE__ +# ifdef __KERNEL_GPU__ + /* Compact structure on the GPU. */ + int x, y, z; +# else + /* SIMD aligned structure for CPU. */ +# ifdef __KERNEL_SSE__ union { __m128i m128; struct { @@ -29,19 +33,21 @@ struct ccl_try_align(16) int3 __forceinline operator __m128i &(); __forceinline int3 &operator=(const int3 &a); -# else /* __KERNEL_SSE__ */ +# else /* __KERNEL_SSE__ */ int x, y, z, w; -# endif /* __KERNEL_SSE__ */ +# endif /* __KERNEL_SSE__ */ +# endif +# ifndef __KERNEL_GPU__ __forceinline int operator[](int i) const; __forceinline int &operator[](int i); +# endif }; -ccl_device_inline int3 make_int3(int i); ccl_device_inline int3 make_int3(int x, int y, int z); -ccl_device_inline void print_int3(const char *label, const int3 &a); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ -CCL_NAMESPACE_END +ccl_device_inline int3 make_int3(int i); +ccl_device_inline void print_int3(ccl_private const char *label, const int3 a); -#endif /* __UTIL_TYPES_INT3_H__ */ +CCL_NAMESPACE_END diff --git a/intern/cycles/util/types_int3_impl.h b/intern/cycles/util/types_int3_impl.h index 1c49e97ad32..830dfa3c658 100644 --- a/intern/cycles/util/types_int3_impl.h +++ b/intern/cycles/util/types_int3_impl.h @@ -1,20 +1,15 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_INT3_IMPL_H__ -#define __UTIL_TYPES_INT3_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." #endif -#ifndef __KERNEL_GPU__ -# include <cstdio> -#endif - CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ # ifdef __KERNEL_SSE__ __forceinline int3::int3() { @@ -45,6 +40,7 @@ __forceinline int3 &int3::operator=(const int3 &a) } # endif /* __KERNEL_SSE__ */ +# ifndef __KERNEL_GPU__ __forceinline int int3::operator[](int i) const { util_assert(i >= 0); @@ -58,34 +54,37 @@ __forceinline int &int3::operator[](int i) util_assert(i < 3); return *(&x + i); } - -ccl_device_inline int3 make_int3(int i) -{ -# ifdef __KERNEL_SSE__ - int3 a(_mm_set1_epi32(i)); -# else - int3 a = {i, i, i, i}; # endif - return a; -} ccl_device_inline int3 make_int3(int x, int y, int z) { -# ifdef __KERNEL_SSE__ - int3 a(_mm_set_epi32(0, z, y, x)); +# if defined(__KERNEL_GPU__) + return {x, y, z}; +# elif defined(__KERNEL_SSE__) + return int3(_mm_set_epi32(0, z, y, x)); # else - int3 a = {x, y, z, 0}; + return {x, y, z, 0}; # endif +} - return a; +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ + +ccl_device_inline int3 make_int3(int i) +{ +#if defined(__KERNEL_GPU__) + return make_int3(i, i, i); +#elif defined(__KERNEL_SSE__) + return int3(_mm_set1_epi32(i)); +#else + return {i, i, i, i}; +#endif } -ccl_device_inline void print_int3(const char *label, const int3 &a) +ccl_device_inline void print_int3(ccl_private const char *label, const int3 a) { +#ifdef __KERNEL_PRINTF__ printf("%s: %d %d %d\n", label, a.x, a.y, a.z); +#endif } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_INT3_IMPL_H__ */ diff --git a/intern/cycles/util/types_int4.h b/intern/cycles/util/types_int4.h index 9d557c01344..1a13c03e60e 100644 --- a/intern/cycles/util/types_int4.h +++ b/intern/cycles/util/types_int4.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_INT4_H__ -#define __UTIL_TYPES_INT4_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,7 +9,7 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct float3; struct float4; @@ -37,17 +36,18 @@ struct ccl_try_align(16) int4 int x, y, z, w; # endif /* __KERNEL_SSE__ */ +# ifndef __KERNEL_GPU__ __forceinline int operator[](int i) const; __forceinline int &operator[](int i); +# endif }; -ccl_device_inline int4 make_int4(int i); ccl_device_inline int4 make_int4(int x, int y, int z, int w); -ccl_device_inline int4 make_int4(const float3 &f); -ccl_device_inline int4 make_int4(const float4 &f); -ccl_device_inline void print_int4(const char *label, const int4 &a); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ -CCL_NAMESPACE_END +ccl_device_inline int4 make_int4(int i); +ccl_device_inline int4 make_int4(const float3 f); +ccl_device_inline int4 make_int4(const float4 f); +ccl_device_inline void print_int4(ccl_private const char *label, const int4 a); -#endif /* __UTIL_TYPES_INT4_H__ */ +CCL_NAMESPACE_END diff --git a/intern/cycles/util/types_int4_impl.h b/intern/cycles/util/types_int4_impl.h index 11e1ede6705..067794e67b4 100644 --- a/intern/cycles/util/types_int4_impl.h +++ b/intern/cycles/util/types_int4_impl.h @@ -1,20 +1,15 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_INT4_IMPL_H__ -#define __UTIL_TYPES_INT4_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." #endif -#ifndef __KERNEL_GPU__ -# include <cstdio> -#endif - CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ # ifdef __KERNEL_SSE__ __forceinline int4::int4() { @@ -45,6 +40,7 @@ __forceinline int4 &int4::operator=(const int4 &a) } # endif /* __KERNEL_SSE__ */ +# ifndef __KERNEL_GPU__ __forceinline int int4::operator[](int i) const { util_assert(i >= 0); @@ -58,55 +54,53 @@ __forceinline int &int4::operator[](int i) util_assert(i < 4); return *(&x + i); } +# endif -ccl_device_inline int4 make_int4(int i) +ccl_device_inline int4 make_int4(int x, int y, int z, int w) { # ifdef __KERNEL_SSE__ - int4 a(_mm_set1_epi32(i)); + return int4(_mm_set_epi32(w, z, y, x)); # else - int4 a = {i, i, i, i}; + return {x, y, z, w}; # endif - return a; } -ccl_device_inline int4 make_int4(int x, int y, int z, int w) +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ + +ccl_device_inline int4 make_int4(int i) { -# ifdef __KERNEL_SSE__ - int4 a(_mm_set_epi32(w, z, y, x)); -# else - int4 a = {x, y, z, w}; -# endif - return a; +#ifdef __KERNEL_SSE__ + return int4(_mm_set1_epi32(i)); +#else + return make_int4(i, i, i, i); +#endif } -ccl_device_inline int4 make_int4(const float3 &f) +ccl_device_inline int4 make_int4(const float3 f) { -# ifdef __KERNEL_SSE__ - int4 a(_mm_cvtps_epi32(f.m128)); -# elif defined(__KERNEL_ONEAPI__) - int4 a = {(int)f.x, (int)f.y, (int)f.z, 0}; -# else - int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w}; -# endif - return a; +#if defined(__KERNEL_GPU__) + return make_int4((int)f.x, (int)f.y, (int)f.z, 0); +#elif defined(__KERNEL_SSE__) + return int4(_mm_cvtps_epi32(f.m128)); +#else + return make_int4((int)f.x, (int)f.y, (int)f.z, (int)f.w); +#endif } -ccl_device_inline int4 make_int4(const float4 &f) +ccl_device_inline int4 make_int4(const float4 f) { -# ifdef __KERNEL_SSE__ - int4 a(_mm_cvtps_epi32(f.m128)); -# else - int4 a = {(int)f.x, (int)f.y, (int)f.z, (int)f.w}; -# endif - return a; +#ifdef __KERNEL_SSE__ + return int4(_mm_cvtps_epi32(f.m128)); +#else + return make_int4((int)f.x, (int)f.y, (int)f.z, (int)f.w); +#endif } -ccl_device_inline void print_int4(const char *label, const int4 &a) +ccl_device_inline void print_int4(ccl_private const char *label, const int4 a) { +#ifdef __KERNEL_PRINTF__ printf("%s: %d %d %d %d\n", label, a.x, a.y, a.z, a.w); +#endif } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_INT4_IMPL_H__ */ diff --git a/intern/cycles/util/types_spectrum.h b/intern/cycles/util/types_spectrum.h new file mode 100644 index 00000000000..c59230b83ae --- /dev/null +++ b/intern/cycles/util/types_spectrum.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2022 Blender Foundation */ + +#ifndef __UTIL_TYPES_SPECTRUM_H__ +#define __UTIL_TYPES_SPECTRUM_H__ + +#ifndef __UTIL_TYPES_H__ +# error "Do not include this file directly, include util/types.h instead." +#endif + +CCL_NAMESPACE_BEGIN + +#define SPECTRUM_CHANNELS 3 +#define SPECTRUM_DATA_TYPE float3 +#define PACKED_SPECTRUM_DATA_TYPE packed_float3 + +using Spectrum = SPECTRUM_DATA_TYPE; +using PackedSpectrum = PACKED_SPECTRUM_DATA_TYPE; + +#define make_spectrum(f) CONCAT(make_, SPECTRUM_DATA_TYPE(f)) +#define load_spectrum(f) CONCAT(load_, SPECTRUM_DATA_TYPE(f)) +#define store_spectrum(s, f) CONCAT(store_, SPECTRUM_DATA_TYPE((s), (f))) + +#define zero_spectrum CONCAT(zero_, SPECTRUM_DATA_TYPE) +#define one_spectrum CONCAT(one_, SPECTRUM_DATA_TYPE) + +#define FOREACH_SPECTRUM_CHANNEL(counter) \ + for (int counter = 0; counter < SPECTRUM_CHANNELS; counter++) + +#define GET_SPECTRUM_CHANNEL(v, i) (((ccl_private float *)(&(v)))[i]) + +CCL_NAMESPACE_END + +#endif /* __UTIL_TYPES_SPECTRUM_H__ */ diff --git a/intern/cycles/util/types_uchar2.h b/intern/cycles/util/types_uchar2.h index 0b3c9bd0331..ce617248e6e 100644 --- a/intern/cycles/util/types_uchar2.h +++ b/intern/cycles/util/types_uchar2.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_UCHAR2_H__ -#define __UTIL_TYPES_UCHAR2_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,17 +9,17 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct uchar2 { uchar x, y; +# ifndef __KERNEL_GPU__ __forceinline uchar operator[](int i) const; __forceinline uchar &operator[](int i); +# endif }; ccl_device_inline uchar2 make_uchar2(uchar x, uchar y); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_UCHAR2_H__ */ diff --git a/intern/cycles/util/types_uchar2_impl.h b/intern/cycles/util/types_uchar2_impl.h index a7254d5eaf2..9f3f3a4efb9 100644 --- a/intern/cycles/util/types_uchar2_impl.h +++ b/intern/cycles/util/types_uchar2_impl.h @@ -10,7 +10,8 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ +# ifndef __KERNEL_GPU__ uchar uchar2::operator[](int i) const { util_assert(i >= 0); @@ -24,13 +25,14 @@ uchar &uchar2::operator[](int i) util_assert(i < 2); return *(&x + i); } +# endif ccl_device_inline uchar2 make_uchar2(uchar x, uchar y) { uchar2 a = {x, y}; return a; } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END diff --git a/intern/cycles/util/types_uchar3.h b/intern/cycles/util/types_uchar3.h index fc213502ada..aed04c4775e 100644 --- a/intern/cycles/util/types_uchar3.h +++ b/intern/cycles/util/types_uchar3.h @@ -10,16 +10,18 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct uchar3 { uchar x, y, z; +# ifndef __KERNEL_GPU__ __forceinline uchar operator[](int i) const; __forceinline uchar &operator[](int i); +# endif }; ccl_device_inline uchar3 make_uchar3(uchar x, uchar y, uchar z); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END diff --git a/intern/cycles/util/types_uchar3_impl.h b/intern/cycles/util/types_uchar3_impl.h index 0c24ffb488a..83eb3c99b3c 100644 --- a/intern/cycles/util/types_uchar3_impl.h +++ b/intern/cycles/util/types_uchar3_impl.h @@ -10,7 +10,8 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ +# ifndef __KERNEL_GPU__ uchar uchar3::operator[](int i) const { util_assert(i >= 0); @@ -24,13 +25,14 @@ uchar &uchar3::operator[](int i) util_assert(i < 3); return *(&x + i); } +# endif ccl_device_inline uchar3 make_uchar3(uchar x, uchar y, uchar z) { uchar3 a = {x, y, z}; return a; } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END diff --git a/intern/cycles/util/types_uchar4.h b/intern/cycles/util/types_uchar4.h index a2a2c945aaa..fb13a98875e 100644 --- a/intern/cycles/util/types_uchar4.h +++ b/intern/cycles/util/types_uchar4.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_UCHAR4_H__ -#define __UTIL_TYPES_UCHAR4_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,17 +9,17 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct uchar4 { uchar x, y, z, w; +# ifndef __KERNEL_GPU__ __forceinline uchar operator[](int i) const; __forceinline uchar &operator[](int i); +# endif }; ccl_device_inline uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_UCHAR4_H__ */ diff --git a/intern/cycles/util/types_uchar4_impl.h b/intern/cycles/util/types_uchar4_impl.h index 8ec6213a37d..244bb98f883 100644 --- a/intern/cycles/util/types_uchar4_impl.h +++ b/intern/cycles/util/types_uchar4_impl.h @@ -10,7 +10,8 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ +# ifndef __KERNEL_GPU__ uchar uchar4::operator[](int i) const { util_assert(i >= 0); @@ -24,13 +25,14 @@ uchar &uchar4::operator[](int i) util_assert(i < 4); return *(&x + i); } +# endif ccl_device_inline uchar4 make_uchar4(uchar x, uchar y, uchar z, uchar w) { uchar4 a = {x, y, z, w}; return a; } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END diff --git a/intern/cycles/util/types_uint2.h b/intern/cycles/util/types_uint2.h index faa0955f903..4d76b628088 100644 --- a/intern/cycles/util/types_uint2.h +++ b/intern/cycles/util/types_uint2.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_UINT2_H__ -#define __UTIL_TYPES_UINT2_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,17 +9,17 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct uint2 { uint x, y; +# ifndef __KERNEL_GPU__ __forceinline uint operator[](uint i) const; __forceinline uint &operator[](uint i); +# endif }; ccl_device_inline uint2 make_uint2(uint x, uint y); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_UINT2_H__ */ diff --git a/intern/cycles/util/types_uint2_impl.h b/intern/cycles/util/types_uint2_impl.h index cac0ba6b531..b508aaf2543 100644 --- a/intern/cycles/util/types_uint2_impl.h +++ b/intern/cycles/util/types_uint2_impl.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_UINT2_IMPL_H__ -#define __UTIL_TYPES_UINT2_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,7 +9,8 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ +# ifndef __KERNEL_GPU__ __forceinline uint uint2::operator[](uint i) const { util_assert(i < 2); @@ -22,14 +22,13 @@ __forceinline uint &uint2::operator[](uint i) util_assert(i < 2); return *(&x + i); } +# endif ccl_device_inline uint2 make_uint2(uint x, uint y) { uint2 a = {x, y}; return a; } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_UINT2_IMPL_H__ */ diff --git a/intern/cycles/util/types_uint3.h b/intern/cycles/util/types_uint3.h index 3ff87bfc791..b1571716fc7 100644 --- a/intern/cycles/util/types_uint3.h +++ b/intern/cycles/util/types_uint3.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_UINT3_H__ -#define __UTIL_TYPES_UINT3_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,17 +9,17 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct uint3 { uint x, y, z; +# ifndef __KERNEL_GPU__ __forceinline uint operator[](uint i) const; __forceinline uint &operator[](uint i); +# endif }; ccl_device_inline uint3 make_uint3(uint x, uint y, uint z); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_UINT3_H__ */ diff --git a/intern/cycles/util/types_uint3_impl.h b/intern/cycles/util/types_uint3_impl.h index 221883a1adb..d36c9f52de9 100644 --- a/intern/cycles/util/types_uint3_impl.h +++ b/intern/cycles/util/types_uint3_impl.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_UINT3_IMPL_H__ -#define __UTIL_TYPES_UINT3_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,7 +9,8 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ +# ifndef __KERNEL_GPU__ __forceinline uint uint3::operator[](uint i) const { util_assert(i < 3); @@ -22,14 +22,13 @@ __forceinline uint &uint3::operator[](uint i) util_assert(i < 3); return *(&x + i); } +# endif ccl_device_inline uint3 make_uint3(uint x, uint y, uint z) { uint3 a = {x, y, z}; return a; } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_UINT3_IMPL_H__ */ diff --git a/intern/cycles/util/types_uint4.h b/intern/cycles/util/types_uint4.h index 504095b2383..4982b30f577 100644 --- a/intern/cycles/util/types_uint4.h +++ b/intern/cycles/util/types_uint4.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_UINT4_H__ -#define __UTIL_TYPES_UINT4_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,17 +9,17 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct uint4 { uint x, y, z, w; +# ifndef __KERNEL_GPU__ __forceinline uint operator[](uint i) const; __forceinline uint &operator[](uint i); +# endif }; ccl_device_inline uint4 make_uint4(uint x, uint y, uint z, uint w); -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_UINT4_H__ */ diff --git a/intern/cycles/util/types_uint4_impl.h b/intern/cycles/util/types_uint4_impl.h index d78db944a1f..1cfdb9e0992 100644 --- a/intern/cycles/util/types_uint4_impl.h +++ b/intern/cycles/util/types_uint4_impl.h @@ -1,8 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#ifndef __UTIL_TYPES_UINT4_IMPL_H__ -#define __UTIL_TYPES_UINT4_IMPL_H__ +#pragma once #ifndef __UTIL_TYPES_H__ # error "Do not include this file directly, include util/types.h instead." @@ -10,7 +9,8 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ +# ifndef __KERNEL_GPU__ __forceinline uint uint4::operator[](uint i) const { util_assert(i < 3); @@ -22,14 +22,13 @@ __forceinline uint &uint4::operator[](uint i) util_assert(i < 3); return *(&x + i); } +# endif ccl_device_inline uint4 make_uint4(uint x, uint y, uint z, uint w) { uint4 a = {x, y, z, w}; return a; } -#endif /* !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) */ +#endif /* __KERNEL_NATIVE_VECTOR_TYPES__ */ CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_UINT4_IMPL_H__ */ diff --git a/intern/cycles/util/types_ushort4.h b/intern/cycles/util/types_ushort4.h index 9a6e12095ba..aef36f63285 100644 --- a/intern/cycles/util/types_ushort4.h +++ b/intern/cycles/util/types_ushort4.h @@ -10,7 +10,7 @@ CCL_NAMESPACE_BEGIN -#if !defined(__KERNEL_GPU__) || defined(__KERNEL_ONEAPI__) +#ifndef __KERNEL_NATIVE_VECTOR_TYPES__ struct ushort4 { uint16_t x, y, z, w; diff --git a/intern/cycles/util/types_vector3.h b/intern/cycles/util/types_vector3.h deleted file mode 100644 index 2e0d68e1bd0..00000000000 --- a/intern/cycles/util/types_vector3.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#ifndef __UTIL_TYPES_VECTOR3_H__ -#define __UTIL_TYPES_VECTOR3_H__ - -#ifndef __UTIL_TYPES_H__ -# error "Do not include this file directly, include util/types.h instead." -#endif - -CCL_NAMESPACE_BEGIN - -#ifndef __KERNEL_GPU__ -template<typename T> class vector3 { - public: - T x, y, z; - - __forceinline vector3(); - __forceinline vector3(const T &a); - __forceinline vector3(const T &x, const T &y, const T &z); -}; -#endif /* __KERNEL_GPU__ */ - -CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_VECTOR3_H__ */ diff --git a/intern/cycles/util/types_vector3_impl.h b/intern/cycles/util/types_vector3_impl.h deleted file mode 100644 index a765780e2d3..00000000000 --- a/intern/cycles/util/types_vector3_impl.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#ifndef __UTIL_TYPES_VECTOR3_IMPL_H__ -#define __UTIL_TYPES_VECTOR3_IMPL_H__ - -#ifndef __UTIL_TYPES_H__ -# error "Do not include this file directly, include util/types.h instead." -#endif - -CCL_NAMESPACE_BEGIN - -#ifndef __KERNEL_GPU__ -template<typename T> ccl_always_inline vector3<T>::vector3() -{ -} - -template<typename T> ccl_always_inline vector3<T>::vector3(const T &a) : x(a), y(a), z(a) -{ -} - -template<typename T> -ccl_always_inline vector3<T>::vector3(const T &x, const T &y, const T &z) : x(x), y(y), z(z) -{ -} -#endif /* __KERNEL_GPU__ */ - -CCL_NAMESPACE_END - -#endif /* __UTIL_TYPES_VECTOR3_IMPL_H__ */ diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index c681dc368bb..d59c179e371 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -4,13 +4,13 @@ set(INC . ../clog - ../glew-mx + ../../source/blender/blenlib ../../source/blender/imbuf ../../source/blender/makesdna ) set(INC_SYS - ${GLEW_INCLUDE_PATH} + ${Epoxy_INCLUDE_DIRS} ) set(SRC @@ -25,6 +25,7 @@ set(SRC intern/GHOST_ISystemPaths.cpp intern/GHOST_ModifierKeys.cpp intern/GHOST_Path-api.cpp + intern/GHOST_PathUtils.cpp intern/GHOST_Rect.cpp intern/GHOST_System.cpp intern/GHOST_TimerManager.cpp @@ -59,6 +60,7 @@ set(SRC intern/GHOST_EventTrackpad.h intern/GHOST_EventWheel.h intern/GHOST_ModifierKeys.h + intern/GHOST_PathUtils.h intern/GHOST_System.h intern/GHOST_SystemPaths.h intern/GHOST_TimerManager.h @@ -71,8 +73,7 @@ set(SRC ) set(LIB - bf_intern_glew_mx - ${GLEW_LIBRARY} + ${Epoxy_LIBRARIES} ) if(WITH_GHOST_DEBUG) @@ -102,42 +103,39 @@ if(WITH_INPUT_NDOF) ) endif() -if(WITH_HEADLESS OR WITH_GHOST_SDL) - if(WITH_HEADLESS) - list(APPEND SRC - intern/GHOST_DisplayManagerNULL.h - intern/GHOST_SystemNULL.h - intern/GHOST_WindowNULL.h +list(APPEND SRC + intern/GHOST_DisplayManagerNULL.h + intern/GHOST_SystemHeadless.h + intern/GHOST_WindowNULL.h +) + +if(WITH_HEADLESS) + add_definitions(-DWITH_HEADLESS) +elseif (WITH_GHOST_SDL) + list(APPEND SRC + intern/GHOST_ContextSDL.cpp + intern/GHOST_DisplayManagerSDL.cpp + intern/GHOST_SystemSDL.cpp + intern/GHOST_WindowSDL.cpp + + intern/GHOST_ContextSDL.h + intern/GHOST_DisplayManagerSDL.h + intern/GHOST_SystemSDL.h + intern/GHOST_WindowSDL.h + ) + add_definitions(-DWITH_GHOST_SDL) + + list(APPEND INC_SYS + ${SDL_INCLUDE_DIR} + ) + if(WITH_SDL_DYNLOAD) + list(APPEND LIB + extern_sdlew ) - add_definitions(-DWITH_HEADLESS) else() - list(APPEND SRC - intern/GHOST_ContextSDL.cpp - intern/GHOST_DisplayManagerSDL.cpp - intern/GHOST_SystemSDL.cpp - intern/GHOST_WindowSDL.cpp - - intern/GHOST_ContextSDL.h - intern/GHOST_DisplayManagerSDL.h - intern/GHOST_SystemSDL.h - intern/GHOST_WindowSDL.h + list(APPEND LIB + ${SDL_LIBRARY} ) - add_definitions(-DWITH_GHOST_SDL) - endif() - - if(NOT WITH_HEADLESS) - list(APPEND INC_SYS - ${SDL_INCLUDE_DIR} - ) - if(WITH_SDL_DYNLOAD) - list(APPEND LIB - extern_sdlew - ) - else() - list(APPEND LIB - ${SDL_LIBRARY} - ) - endif() endif() elseif(APPLE AND NOT WITH_GHOST_X11) @@ -155,13 +153,11 @@ elseif(APPLE AND NOT WITH_GHOST_X11) intern/GHOST_WindowViewCocoa.h ) - if(NOT WITH_GL_EGL) - list(APPEND SRC - intern/GHOST_ContextCGL.mm + list(APPEND SRC + intern/GHOST_ContextCGL.mm - intern/GHOST_ContextCGL.h - ) - endif() + intern/GHOST_ContextCGL.h + ) if(WITH_INPUT_NDOF) list(APPEND SRC @@ -195,13 +191,11 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND) intern/GHOST_WindowX11.h ) - if(NOT WITH_GL_EGL) - list(APPEND SRC - intern/GHOST_ContextGLX.cpp + list(APPEND SRC + intern/GHOST_ContextGLX.cpp - intern/GHOST_ContextGLX.h - ) - endif() + intern/GHOST_ContextGLX.h + ) if(WITH_GHOST_XDND) add_definitions(-DWITH_XDND) @@ -248,10 +242,6 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND) ) endif() - if(WITH_X11_ALPHA) - add_definitions(-DWITH_X11_ALPHA) - endif() - if(WITH_X11_XINPUT) add_definitions(-DWITH_X11_XINPUT) list(APPEND INC_SYS @@ -298,6 +288,7 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND) include(CheckSymbolExists) set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE") check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE) + unset(CMAKE_REQUIRED_DEFINITIONS) if(HAVE_MEMFD_CREATE) add_definitions(-DHAVE_MEMFD_CREATE) endif() @@ -431,13 +422,11 @@ elseif(WIN32) intern/GHOST_Wintab.h ) - if(NOT WITH_GL_EGL) - list(APPEND SRC - intern/GHOST_ContextWGL.cpp + list(APPEND SRC + intern/GHOST_ContextWGL.cpp - intern/GHOST_ContextWGL.h - ) - endif() + intern/GHOST_ContextWGL.h + ) if(WITH_INPUT_IME) add_definitions(-DWITH_INPUT_IME) @@ -458,7 +447,7 @@ elseif(WIN32) endif() endif() -if(WITH_GL_EGL AND NOT (WITH_HEADLESS OR WITH_GHOST_SDL)) +if(UNIX AND NOT APPLE) list(APPEND SRC intern/GHOST_ContextEGL.cpp @@ -548,11 +537,8 @@ if(WITH_XR_OPENXR) list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_WAYLAND) endif() if(WITH_GHOST_X11) - if(WITH_GL_EGL) - list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_EGL) - else() - list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_XLIB) - endif() + list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_EGL) + list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_XLIB) endif() endif() @@ -561,6 +547,4 @@ if(WITH_XR_OPENXR) unset(XR_PLATFORM_DEFINES) endif() -add_definitions(${GL_DEFINITIONS}) - blender_add_lib(bf_intern_ghost "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 4cbc0d65b11..f01f439718f 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -27,6 +27,7 @@ typedef bool (*GHOST_EventCallbackProcPtr)(GHOST_EventHandle event, GHOST_TUserD * \return a handle to the system. */ extern GHOST_SystemHandle GHOST_CreateSystem(void); +extern GHOST_SystemHandle GHOST_CreateSystemBackground(void); /** * Specifies whether debug messages are to be enabled for the specific system handle. diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 91cf1c4c558..0dd855bb513 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -120,6 +120,7 @@ class GHOST_ISystem { * \return An indication of success. */ static GHOST_TSuccess createSystem(); + static GHOST_TSuccess createSystemBackground(); /** * Disposes the one and only system. @@ -277,8 +278,7 @@ class GHOST_ISystem { */ virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window, - const bool stereoVisual, - const bool alphaBackground = 0) = 0; + const bool stereoVisual) = 0; /** * Updates the resolution while in fullscreen mode. diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 495fb739978..adc45285f94 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -61,7 +61,6 @@ typedef struct { typedef enum { GHOST_glStereoVisual = (1 << 0), GHOST_glDebugContext = (1 << 1), - GHOST_glAlphaBackground = (1 << 2), } GHOST_GLFlags; typedef enum GHOST_DialogOptions { diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 65e7de707ec..62e1e470010 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -30,6 +30,14 @@ GHOST_SystemHandle GHOST_CreateSystem(void) return (GHOST_SystemHandle)system; } +GHOST_SystemHandle GHOST_CreateSystemBackground(void) +{ + GHOST_ISystem::createSystemBackground(); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + + return (GHOST_SystemHandle)system; +} + void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, GHOST_Debug debug) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; diff --git a/intern/ghost/intern/GHOST_Context.cpp b/intern/ghost/intern/GHOST_Context.cpp index f9aa80dc13d..aa379efbc1f 100644 --- a/intern/ghost/intern/GHOST_Context.cpp +++ b/intern/ghost/intern/GHOST_Context.cpp @@ -10,7 +10,7 @@ #include "GHOST_Context.h" #ifdef _WIN32 -# include <GL/wglew.h> // only for symbolic constants, do not use API functions +# include <epoxy/wgl.h> # include <tchar.h> # # ifndef ERROR_PROFILE_DOES_NOT_MATCH_DEVICE @@ -35,7 +35,7 @@ bool win32_silent_chk(bool result) bool win32_chk(bool result, const char *file, int line, const char *text) { if (!result) { - LPTSTR formattedMsg = NULL; + LPTSTR formattedMsg = nullptr; DWORD error = GetLastError(); @@ -87,12 +87,12 @@ bool win32_chk(bool result, const char *file, int line, const char *text) default: { count = FormatMessage((FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS), - NULL, + nullptr, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)(&formattedMsg), 0, - NULL); + nullptr); msg = count > 0 ? formattedMsg : "<no system message>\n"; break; @@ -113,8 +113,9 @@ bool win32_chk(bool result, const char *file, int line, const char *text) SetLastError(NO_ERROR); - if (count != 0) + if (count != 0) { LocalFree(formattedMsg); + } } return result; @@ -122,11 +123,6 @@ bool win32_chk(bool result, const char *file, int line, const char *text) #endif // _WIN32 -void GHOST_Context::initContextGLEW() -{ - GLEW_CHK(glewInit()); -} - void GHOST_Context::initClearGL() { glClearColor(0.294, 0.294, 0.294, 0.000); diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h index e707f1c3475..3546fb6bbc7 100644 --- a/intern/ghost/intern/GHOST_Context.h +++ b/intern/ghost/intern/GHOST_Context.h @@ -11,7 +11,7 @@ #include "GHOST_IContext.h" #include "GHOST_Types.h" -#include "glew-mx.h" +#include <epoxy/gl.h> #include <cstdlib> // for NULL @@ -136,8 +136,6 @@ class GHOST_Context : public GHOST_IContext { } protected: - void initContextGLEW(); - bool m_stereoVisual; /** Caller specified, not for internal use. */ diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index badc3241107..fa6d6fc6fa0 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -105,8 +105,6 @@ class GHOST_ContextCGL : public GHOST_Context { /** The virtualized default frame-buffer's texture. */ MTLTexture *m_defaultFramebufferMetalTexture; - bool m_coreProfile; - const bool m_debug; /** The first created OpenGL context (for sharing display lists) */ diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm index dd800ef52a3..6da44ec481c 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.mm +++ b/intern/ghost/intern/GHOST_ContextCGL.mm @@ -58,12 +58,6 @@ GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual, m_defaultFramebufferMetalTexture(nil), m_debug(false) { -#if defined(WITH_GL_PROFILE_CORE) - m_coreProfile = true; -#else - m_coreProfile = false; -#endif - if (m_metalView) { metalInit(); } @@ -197,7 +191,6 @@ GHOST_TSuccess GHOST_ContextCGL::updateDrawingContext() } static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs, - bool coreProfile, bool stereoVisual, bool needAlpha, bool softwareGL) @@ -205,7 +198,7 @@ static void makeAttribList(std::vector<NSOpenGLPixelFormatAttribute> &attribs, attribs.clear(); attribs.push_back(NSOpenGLPFAOpenGLProfile); - attribs.push_back(coreProfile ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy); + attribs.push_back(NSOpenGLProfileVersion3_2Core); /* Pixel Format Attributes for the windowed NSOpenGLContext. */ attribs.push_back(NSOpenGLPFADoubleBuffer); @@ -245,7 +238,7 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext() std::vector<NSOpenGLPixelFormatAttribute> attribs; attribs.reserve(40); - makeAttribList(attribs, m_coreProfile, m_stereoVisual, needAlpha, softwareGL); + makeAttribList(attribs, m_stereoVisual, needAlpha, softwareGL); NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attribs[0]]; if (pixelFormat == nil) { @@ -274,8 +267,6 @@ GHOST_TSuccess GHOST_ContextCGL::initializeDrawingContext() } #endif - initContextGLEW(); - if (m_metalView) { if (m_defaultFramebuffer == 0) { /* Create a virtual frame-buffer. */ diff --git a/intern/ghost/intern/GHOST_ContextD3D.cpp b/intern/ghost/intern/GHOST_ContextD3D.cpp index ded76daa145..4fc05cf912c 100644 --- a/intern/ghost/intern/GHOST_ContextD3D.cpp +++ b/intern/ghost/intern/GHOST_ContextD3D.cpp @@ -10,8 +10,7 @@ #include <iostream> #include <string> -#include <GL/glew.h> -#include <GL/wglew.h> +#include <epoxy/wgl.h> #include "GHOST_ContextD3D.h" #include "GHOST_ContextWGL.h" /* For shared drawing */ diff --git a/intern/ghost/intern/GHOST_ContextEGL.cpp b/intern/ghost/intern/GHOST_ContextEGL.cpp index 8c44dfe0158..ef13133d3a3 100644 --- a/intern/ghost/intern/GHOST_ContextEGL.cpp +++ b/intern/ghost/intern/GHOST_ContextEGL.cpp @@ -151,19 +151,6 @@ static bool egl_chk(bool result, # define EGL_CHK(x) egl_chk(x) #endif -static inline bool bindAPI(EGLenum api) -{ - if (EGLEW_VERSION_1_2) { - return (EGL_CHK(eglBindAPI(api)) == EGL_TRUE); - } - - return false; -} - -#ifdef WITH_GL_ANGLE -HMODULE GHOST_ContextEGL::s_d3dcompiler = nullptr; -#endif - EGLContext GHOST_ContextEGL::s_gl_sharedContext = EGL_NO_CONTEXT; EGLint GHOST_ContextEGL::s_gl_sharedCount = 0; @@ -256,7 +243,7 @@ GHOST_TSuccess GHOST_ContextEGL::swapBuffers() GHOST_TSuccess GHOST_ContextEGL::setSwapInterval(int interval) { - if (EGLEW_VERSION_1_1) { + if (epoxy_egl_version(m_display) >= 11) { if (EGL_CHK(::eglSwapInterval(m_display, interval))) { m_swap_interval = interval; @@ -313,26 +300,13 @@ GHOST_TSuccess GHOST_ContextEGL::releaseDrawingContext() return GHOST_kFailure; } -bool GHOST_ContextEGL::initContextEGLEW() +inline bool GHOST_ContextEGL::bindAPI(EGLenum api) { - /* We have to manually get this function before we can call eglewInit, since - * it requires a display argument. glewInit() does the same, but we only want - * to initialize EGLEW here. */ - eglGetDisplay = (PFNEGLGETDISPLAYPROC)eglGetProcAddress("eglGetDisplay"); - if (eglGetDisplay == nullptr) { - return false; - } - - if (!EGL_CHK((m_display = ::eglGetDisplay(m_nativeDisplay)) != EGL_NO_DISPLAY)) { - return false; - } - - if (GLEW_CHK(eglewInit(m_display)) != GLEW_OK) { - fprintf(stderr, "Warning! EGLEW failed to initialize properly.\n"); - return false; + if (epoxy_egl_version(m_display) >= 12) { + return (EGL_CHK(eglBindAPI(api)) == EGL_TRUE); } - return true; + return false; } static const std::string &api_string(EGLenum api) @@ -355,34 +329,41 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext() } m_stereoVisual = false; /* It doesn't matter what the Window wants. */ - if (!initContextEGLEW()) { - return GHOST_kFailure; - } - -#ifdef WITH_GL_ANGLE - /* `d3dcompiler_XX.dll` needs to be loaded before ANGLE will work. */ - if (s_d3dcompiler == nullptr) { - s_d3dcompiler = LoadLibrary(D3DCOMPILER); - - WIN32_CHK(s_d3dcompiler != nullptr); - - if (s_d3dcompiler == nullptr) { - fprintf(stderr, "LoadLibrary(\"" D3DCOMPILER "\") failed!\n"); - return GHOST_kFailure; - } - } -#endif - EGLDisplay prev_display = eglGetCurrentDisplay(); EGLSurface prev_draw = eglGetCurrentSurface(EGL_DRAW); EGLSurface prev_read = eglGetCurrentSurface(EGL_READ); EGLContext prev_context = eglGetCurrentContext(); - EGLint egl_major, egl_minor; + EGLint egl_major = 0, egl_minor = 0; - if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor))) { + if (!EGL_CHK((m_display = ::eglGetDisplay(m_nativeDisplay)) != EGL_NO_DISPLAY)) { goto error; } + + if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor)) || + (egl_major == 0 && egl_minor == 0)) { + /* We failed to create a regular render window, retry and see if we can create a headless + * render context. */ + ::eglTerminate(m_display); + + const char *egl_extension_st = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + assert(egl_extension_st != nullptr); + assert(strstr(egl_extension_st, "EGL_MESA_platform_surfaceless") != nullptr); + if (egl_extension_st == nullptr || + strstr(egl_extension_st, "EGL_MESA_platform_surfaceless") == nullptr) { + goto error; + } + + m_display = eglGetPlatformDisplayEXT( + EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, nullptr); + + if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor))) { + goto error; + } + /* Because the first eglInitialize will print an error to the terminal, print a "success" + * message here to let the user know that we successfully recovered from the error. */ + fprintf(stderr, "\nManaged to successfully fallback to surfaceless EGL rendering!\n\n"); + } #ifdef WITH_GHOST_DEBUG fprintf(stderr, "EGL Version %d.%d\n", egl_major, egl_minor); #endif @@ -398,7 +379,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext() attrib_list.reserve(20); - if (m_api == EGL_OPENGL_ES_API && EGLEW_VERSION_1_2) { + if (m_api == EGL_OPENGL_ES_API && epoxy_egl_version(m_display) >= 12) { /* According to the spec it seems that you are required to set EGL_RENDERABLE_TYPE, * but some implementations (ANGLE) do not seem to care. */ @@ -421,9 +402,11 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext() m_contextMinorVersion); } - if (!((m_contextMajorVersion == 1) || (m_contextMajorVersion == 2 && EGLEW_VERSION_1_3) || - (m_contextMajorVersion == 3 && /*EGLEW_VERSION_1_4 &&*/ EGLEW_KHR_create_context) || - (m_contextMajorVersion == 3 && EGLEW_VERSION_1_5))) { + if (!((m_contextMajorVersion == 1) || + (m_contextMajorVersion == 2 && epoxy_egl_version(m_display) >= 13) || + (m_contextMajorVersion == 3 && + epoxy_has_egl_extension(m_display, "KHR_create_context")) || + (m_contextMajorVersion == 3 && epoxy_egl_version(m_display) >= 15))) { fprintf(stderr, "Warning! May not be able to create a version %d.%d ES context with version %d.%d " "of EGL\n", @@ -488,7 +471,8 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext() } attrib_list.clear(); - if (EGLEW_VERSION_1_5 || EGLEW_KHR_create_context) { + if (epoxy_egl_version(m_display) >= 15 || + epoxy_has_egl_extension(m_display, "KHR_create_context")) { if (m_api == EGL_OPENGL_API || m_api == EGL_OPENGL_ES_API) { if (m_contextMajorVersion != 0) { attrib_list.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); @@ -530,7 +514,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext() } } - if (m_api == EGL_OPENGL_API || EGLEW_VERSION_1_5) { + if (m_api == EGL_OPENGL_API || epoxy_egl_version(m_display) >= 15) { if (m_contextResetNotificationStrategy != 0) { attrib_list.push_back(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR); attrib_list.push_back(m_contextResetNotificationStrategy); @@ -598,10 +582,10 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext() goto error; } - initContextGLEW(); - - initClearGL(); - ::eglSwapBuffers(m_display, m_surface); + if (m_nativeWindow != 0) { + initClearGL(); + ::eglSwapBuffers(m_display, m_surface); + } return GHOST_kSuccess; diff --git a/intern/ghost/intern/GHOST_ContextEGL.h b/intern/ghost/intern/GHOST_ContextEGL.h index 3250dc94978..3ccd34f0338 100644 --- a/intern/ghost/intern/GHOST_ContextEGL.h +++ b/intern/ghost/intern/GHOST_ContextEGL.h @@ -10,7 +10,8 @@ #include "GHOST_Context.h" #include "GHOST_System.h" -#include <GL/eglew.h> +#include <epoxy/egl.h> +#include <epoxy/gl.h> #ifndef GHOST_OPENGL_EGL_CONTEXT_FLAGS # define GHOST_OPENGL_EGL_CONTEXT_FLAGS 0 @@ -96,7 +97,7 @@ class GHOST_ContextEGL : public GHOST_Context { EGLContext getContext() const; private: - bool initContextEGLEW(); + bool bindAPI(EGLenum api); const GHOST_System *const m_system; @@ -129,8 +130,4 @@ class GHOST_ContextEGL : public GHOST_Context { static EGLContext s_vg_sharedContext; static EGLint s_vg_sharedCount; - -#ifdef WITH_GL_ANGLE - static HMODULE s_d3dcompiler; -#endif }; diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index b4a076e4598..ed1c874c236 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -95,11 +95,6 @@ GHOST_TSuccess GHOST_ContextGLX::releaseDrawingContext() return ::glXMakeCurrent(m_display, None, nullptr) ? GHOST_kSuccess : GHOST_kFailure; } -void GHOST_ContextGLX::initContextGLXEW() -{ - initContextGLEW(); -} - GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() { GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store); @@ -278,18 +273,11 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() glXMakeCurrent(m_display, m_window, m_context); - /* Seems that this has to be called after #glXMakeCurrent, - * which means we cannot use `glX` extensions until after we create a context. */ - initContextGLXEW(); - if (m_window) { initClearGL(); ::glXSwapBuffers(m_display, m_window); } - /* re initialize to get the extensions properly */ - initContextGLXEW(); - version = glGetString(GL_VERSION); if (!version || version[0] < '3' || ((version[0] == '3') && (version[2] < '3'))) { @@ -318,7 +306,7 @@ GHOST_TSuccess GHOST_ContextGLX::releaseNativeHandles() GHOST_TSuccess GHOST_ContextGLX::setSwapInterval(int interval) { - if (!GLXEW_EXT_swap_control) { + if (!epoxy_has_glx_extension(m_display, DefaultScreen(m_display), "GLX_EXT_swap_control")) { ::glXSwapIntervalEXT(m_display, m_window, interval); return GHOST_kSuccess; } @@ -327,7 +315,7 @@ GHOST_TSuccess GHOST_ContextGLX::setSwapInterval(int interval) GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int &intervalOut) { - if (GLXEW_EXT_swap_control) { + if (epoxy_has_glx_extension(m_display, DefaultScreen(m_display), "GLX_EXT_swap_control")) { unsigned int interval = 0; ::glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &interval); diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h index c6184bbd3da..d526e6b1b32 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.h +++ b/intern/ghost/intern/GHOST_ContextGLX.h @@ -9,7 +9,7 @@ #include "GHOST_Context.h" -#include <GL/glxew.h> +#include <epoxy/glx.h> #ifndef GHOST_OPENGL_GLX_CONTEXT_FLAGS /* leave as convenience define for the future */ @@ -89,8 +89,6 @@ class GHOST_ContextGLX : public GHOST_Context { GHOST_TSuccess getSwapInterval(int &intervalOut); private: - void initContextGLXEW(); - Display *m_display; GLXFBConfig m_fbconfig; Window m_window; diff --git a/intern/ghost/intern/GHOST_ContextSDL.cpp b/intern/ghost/intern/GHOST_ContextSDL.cpp index 5b02fe1c1e6..63b5927895d 100644 --- a/intern/ghost/intern/GHOST_ContextSDL.cpp +++ b/intern/ghost/intern/GHOST_ContextSDL.cpp @@ -138,8 +138,6 @@ GHOST_TSuccess GHOST_ContextSDL::initializeDrawingContext() success = (SDL_GL_MakeCurrent(m_window, m_context) < 0) ? GHOST_kFailure : GHOST_kSuccess; - initContextGLEW(); - initClearGL(); SDL_GL_SwapWindow(m_window); diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp index 7417358e9ae..d3c190a13b1 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.cpp +++ b/intern/ghost/intern/GHOST_ContextWGL.cpp @@ -87,7 +87,7 @@ GHOST_TSuccess GHOST_ContextWGL::swapBuffers() GHOST_TSuccess GHOST_ContextWGL::setSwapInterval(int interval) { - if (WGLEW_EXT_swap_control) + if (epoxy_has_wgl_extension(m_hDC, "WGL_EXT_swap_control")) return WIN32_CHK(::wglSwapIntervalEXT(interval)) == TRUE ? GHOST_kSuccess : GHOST_kFailure; else return GHOST_kFailure; @@ -95,7 +95,7 @@ GHOST_TSuccess GHOST_ContextWGL::setSwapInterval(int interval) GHOST_TSuccess GHOST_ContextWGL::getSwapInterval(int &intervalOut) { - if (WGLEW_EXT_swap_control) { + if (epoxy_has_wgl_extension(m_hDC, "WGL_EXT_swap_control")) { intervalOut = ::wglGetSwapIntervalEXT(); return GHOST_kSuccess; } @@ -266,89 +266,6 @@ static HWND clone_window(HWND hWnd, LPVOID lpParam) return hwndCloned; } -void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD) -{ - HWND dummyHWND = NULL; - - HDC dummyHDC = NULL; - HGLRC dummyHGLRC = NULL; - - HDC prevHDC; - HGLRC prevHGLRC; - - int iPixelFormat; - - SetLastError(NO_ERROR); - - prevHDC = ::wglGetCurrentDC(); - WIN32_CHK(GetLastError() == NO_ERROR); - - prevHGLRC = ::wglGetCurrentContext(); - WIN32_CHK(GetLastError() == NO_ERROR); - - iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD); - - if (iPixelFormat == 0) - goto finalize; - - PIXELFORMATDESCRIPTOR chosenPFD; - if (!WIN32_CHK( - ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD))) - goto finalize; - - if (m_hWnd) { - dummyHWND = clone_window(m_hWnd, NULL); - - if (dummyHWND == NULL) - goto finalize; - - dummyHDC = GetDC(dummyHWND); - } - - if (!WIN32_CHK(dummyHDC != NULL)) - goto finalize; - - if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD))) - goto finalize; - - dummyHGLRC = ::wglCreateContext(dummyHDC); - - if (!WIN32_CHK(dummyHGLRC != NULL)) - goto finalize; - - if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC))) - goto finalize; - - if (GLEW_CHK(glewInit()) != GLEW_OK) { - fprintf(stderr, "Warning! Dummy GLEW/WGLEW failed to initialize properly.\n"); - } - - /* The following are not technically WGLEW, but they also require a context to work. */ - -#ifndef NDEBUG - free((void *)m_dummyRenderer); - free((void *)m_dummyVendor); - free((void *)m_dummyVersion); - - m_dummyRenderer = _strdup(reinterpret_cast<const char *>(glGetString(GL_RENDERER))); - m_dummyVendor = _strdup(reinterpret_cast<const char *>(glGetString(GL_VENDOR))); - m_dummyVersion = _strdup(reinterpret_cast<const char *>(glGetString(GL_VERSION))); -#endif - -finalize: - WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC)); - - if (dummyHGLRC != NULL) - WIN32_CHK(::wglDeleteContext(dummyHGLRC)); - - if (dummyHWND != NULL) { - if (dummyHDC != NULL) - WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC)); - - WIN32_CHK(::DestroyWindow(dummyHWND)); - } -} - static void makeAttribList(std::vector<int> &out, bool stereoVisual, bool needAlpha) { out.clear(); @@ -385,6 +302,130 @@ static void makeAttribList(std::vector<int> &out, bool stereoVisual, bool needAl out.push_back(0); } +/* Temporary context used to create the actual context. We need ARB pixel format + * and context extensions, which are only available within a context. */ +struct DummyContextWGL { + HWND dummyHWND = NULL; + + HDC dummyHDC = NULL; + HGLRC dummyHGLRC = NULL; + + HDC prevHDC = NULL; + HGLRC prevHGLRC = NULL; + + int dummyPixelFormat = 0; + + PIXELFORMATDESCRIPTOR preferredPFD; + + bool has_WGL_ARB_pixel_format = false; + bool has_WGL_ARB_create_context = false; + bool has_WGL_ARB_create_context_profile = false; + bool has_WGL_ARB_create_context_robustness = false; + + DummyContextWGL(HDC hDC, HWND hWnd, bool stereoVisual, bool needAlpha) + { + preferredPFD = { + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + (DWORD)(PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER | /* support double-buffering */ + (stereoVisual ? PFD_STEREO : 0) | /* support stereo */ + ( +#ifdef WIN32_COMPOSITING + /* Support composition for transparent background. */ + needAlpha ? PFD_SUPPORT_COMPOSITION : +#endif + 0)), + PFD_TYPE_RGBA, /* color type */ + (BYTE)(needAlpha ? 32 : 24), /* preferred color depth */ + 0, + 0, + 0, + 0, + 0, + 0, /* color bits (ignored) */ + (BYTE)(needAlpha ? 8 : 0), /* alpha buffer */ + 0, /* alpha shift (ignored) */ + 0, /* no accumulation buffer */ + 0, + 0, + 0, + 0, /* accum bits (ignored) */ + 0, /* depth buffer */ + 0, /* stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, + 0, + 0 /* layer, visible, and damage masks (ignored) */ + }; + + SetLastError(NO_ERROR); + + prevHDC = ::wglGetCurrentDC(); + WIN32_CHK(GetLastError() == NO_ERROR); + + prevHGLRC = ::wglGetCurrentContext(); + WIN32_CHK(GetLastError() == NO_ERROR); + + dummyPixelFormat = choose_pixel_format_legacy(hDC, preferredPFD); + + if (dummyPixelFormat == 0) + return; + + PIXELFORMATDESCRIPTOR chosenPFD; + if (!WIN32_CHK(::DescribePixelFormat( + hDC, dummyPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD))) + return; + + if (hWnd) { + dummyHWND = clone_window(hWnd, NULL); + + if (dummyHWND == NULL) + return; + + dummyHDC = GetDC(dummyHWND); + } + + if (!WIN32_CHK(dummyHDC != NULL)) + return; + + if (!WIN32_CHK(::SetPixelFormat(dummyHDC, dummyPixelFormat, &chosenPFD))) + return; + + dummyHGLRC = ::wglCreateContext(dummyHDC); + + if (!WIN32_CHK(dummyHGLRC != NULL)) + return; + + if (!WIN32_CHK(::wglMakeCurrent(dummyHDC, dummyHGLRC))) + return; + + has_WGL_ARB_pixel_format = epoxy_has_wgl_extension(hDC, "WGL_ARB_pixel_format"); + has_WGL_ARB_create_context = epoxy_has_wgl_extension(hDC, "WGL_ARB_create_context"); + has_WGL_ARB_create_context_profile = epoxy_has_wgl_extension(hDC, + "WGL_ARB_create_context_profile"); + has_WGL_ARB_create_context_robustness = epoxy_has_wgl_extension( + hDC, "WGL_ARB_create_context_robustness"); + } + + ~DummyContextWGL() + { + WIN32_CHK(::wglMakeCurrent(prevHDC, prevHGLRC)); + + if (dummyHGLRC != NULL) + WIN32_CHK(::wglDeleteContext(dummyHGLRC)); + + if (dummyHWND != NULL) { + if (dummyHDC != NULL) + WIN32_CHK(::ReleaseDC(dummyHWND, dummyHDC)); + + WIN32_CHK(::DestroyWindow(dummyHWND)); + } + } +}; + int GHOST_ContextWGL::_choose_pixel_format_arb_1(bool stereoVisual, bool needAlpha) { std::vector<int> iAttributes; @@ -454,58 +495,6 @@ int GHOST_ContextWGL::choose_pixel_format_arb(bool stereoVisual, bool needAlpha) return iPixelFormat; } -int GHOST_ContextWGL::choose_pixel_format(bool stereoVisual, bool needAlpha) -{ - PIXELFORMATDESCRIPTOR preferredPFD = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - (DWORD)(PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER | /* support double-buffering */ - (stereoVisual ? PFD_STEREO : 0) | /* support stereo */ - ( -#ifdef WIN32_COMPOSITING - /* Support composition for transparent background. */ - needAlpha ? PFD_SUPPORT_COMPOSITION : -#endif - 0)), - PFD_TYPE_RGBA, /* color type */ - (BYTE)(needAlpha ? 32 : 24), /* preferred color depth */ - 0, - 0, - 0, - 0, - 0, - 0, /* color bits (ignored) */ - (BYTE)(needAlpha ? 8 : 0), /* alpha buffer */ - 0, /* alpha shift (ignored) */ - 0, /* no accumulation buffer */ - 0, - 0, - 0, - 0, /* accum bits (ignored) */ - 0, /* depth buffer */ - 0, /* stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, - 0, - 0 /* layer, visible, and damage masks (ignored) */ - }; - - initContextWGLEW(preferredPFD); - - int iPixelFormat = 0; - - if (WGLEW_ARB_pixel_format) - iPixelFormat = choose_pixel_format_arb(stereoVisual, needAlpha); - - if (iPixelFormat == 0) - iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD); - - return iPixelFormat; -} - #ifndef NDEBUG static void reportContextString(const char *name, const char *dummy, const char *context) { @@ -526,107 +515,96 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() HDC prevHDC = ::wglGetCurrentDC(); WIN32_CHK(GetLastError() == NO_ERROR); - if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) { + { const bool needAlpha = m_alphaBackground; - int iPixelFormat; - int lastPFD; - - PIXELFORMATDESCRIPTOR chosenPFD; - - iPixelFormat = choose_pixel_format(m_stereoVisual, needAlpha); + DummyContextWGL dummy(m_hDC, m_hWnd, m_stereoVisual, needAlpha); - if (iPixelFormat == 0) { - goto error; - } + if (!dummy.has_WGL_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) { + int iPixelFormat = 0; - lastPFD = ::DescribePixelFormat( - m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); - - if (!WIN32_CHK(lastPFD != 0)) { - goto error; - } + if (dummy.has_WGL_ARB_pixel_format) + iPixelFormat = choose_pixel_format_arb(m_stereoVisual, needAlpha); - if (needAlpha && chosenPFD.cAlphaBits == 0) - fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); + if (iPixelFormat == 0) + iPixelFormat = choose_pixel_format_legacy(m_hDC, dummy.preferredPFD); - if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) { - goto error; - } - } + if (iPixelFormat == 0) { + goto error; + } - if (WGLEW_ARB_create_context) { - int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + PIXELFORMATDESCRIPTOR chosenPFD; + int lastPFD = ::DescribePixelFormat( + m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); -#ifdef WITH_GLEW_ES - int profileBitES = m_contextProfileMask & WGL_CONTEXT_ES_PROFILE_BIT_EXT; -#endif + if (!WIN32_CHK(lastPFD != 0)) { + goto error; + } - if (!WGLEW_ARB_create_context_profile && profileBitCore) - fprintf(stderr, "Warning! OpenGL core profile not available.\n"); + if (needAlpha && chosenPFD.cAlphaBits == 0) + fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); - if (!WGLEW_ARB_create_context_profile && profileBitCompat) - fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n"); + if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) { + goto error; + } + } -#ifdef WITH_GLEW_ES - if (!WGLEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1) - fprintf(stderr, "Warning! OpenGL ES profile not available.\n"); + if (dummy.has_WGL_ARB_create_context) { + int profileBitCore = m_contextProfileMask & WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + int profileBitCompat = m_contextProfileMask & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - if (!WGLEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2) - fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n"); -#endif + if (!dummy.has_WGL_ARB_create_context_profile && profileBitCore) + fprintf(stderr, "Warning! OpenGL core profile not available.\n"); - int profileMask = 0; + if (!dummy.has_WGL_ARB_create_context_profile && profileBitCompat) + fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n"); - if (WGLEW_ARB_create_context_profile && profileBitCore) - profileMask |= profileBitCore; + int profileMask = 0; - if (WGLEW_ARB_create_context_profile && profileBitCompat) - profileMask |= profileBitCompat; + if (dummy.has_WGL_ARB_create_context_profile && profileBitCore) + profileMask |= profileBitCore; -#ifdef WITH_GLEW_ES - if (WGLEW_EXT_create_context_es_profile && profileBitES) - profileMask |= profileBitES; -#endif + if (dummy.has_WGL_ARB_create_context_profile && profileBitCompat) + profileMask |= profileBitCompat; - if (profileMask != m_contextProfileMask) - fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits."); + if (profileMask != m_contextProfileMask) + fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits."); - std::vector<int> iAttributes; + std::vector<int> iAttributes; - if (profileMask) { - iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); - iAttributes.push_back(profileMask); - } - - if (m_contextMajorVersion != 0) { - iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); - iAttributes.push_back(m_contextMajorVersion); - } + if (profileMask) { + iAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); + iAttributes.push_back(profileMask); + } - if (m_contextMinorVersion != 0) { - iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); - iAttributes.push_back(m_contextMinorVersion); - } + if (m_contextMajorVersion != 0) { + iAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); + iAttributes.push_back(m_contextMajorVersion); + } - if (m_contextFlags != 0) { - iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB); - iAttributes.push_back(m_contextFlags); - } + if (m_contextMinorVersion != 0) { + iAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); + iAttributes.push_back(m_contextMinorVersion); + } - if (m_contextResetNotificationStrategy != 0) { - if (WGLEW_ARB_create_context_robustness) { - iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); - iAttributes.push_back(m_contextResetNotificationStrategy); + if (m_contextFlags != 0) { + iAttributes.push_back(WGL_CONTEXT_FLAGS_ARB); + iAttributes.push_back(m_contextFlags); } - else { - fprintf(stderr, "Warning! Cannot set the reset notification strategy."); + + if (m_contextResetNotificationStrategy != 0) { + if (dummy.has_WGL_ARB_create_context_robustness) { + iAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); + iAttributes.push_back(m_contextResetNotificationStrategy); + } + else { + fprintf(stderr, "Warning! Cannot set the reset notification strategy."); + } } - } - iAttributes.push_back(0); + iAttributes.push_back(0); - m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, NULL, &(iAttributes[0])); + m_hGLRC = ::wglCreateContextAttribsARB(m_hDC, NULL, &(iAttributes[0])); + } } /* Silence warnings interpreted as errors by users when trying to get @@ -651,8 +629,6 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() goto error; } - initContextGLEW(); - if (is_crappy_intel_card()) { /* Some Intel cards with context 4.1 or 4.2 * don't have the point sprite enabled by default. diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h index ca0bf70b128..c02c0616422 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.h +++ b/intern/ghost/intern/GHOST_ContextWGL.h @@ -11,7 +11,7 @@ #include "GHOST_Context.h" -#include <GL/wglew.h> +#include <epoxy/wgl.h> #ifndef GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY # define GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY 0 @@ -86,12 +86,9 @@ class GHOST_ContextWGL : public GHOST_Context { GHOST_TSuccess getSwapInterval(int &intervalOut); private: - int choose_pixel_format(bool stereoVisual, bool needAlpha); int choose_pixel_format_arb(bool stereoVisual, bool needAlpha); int _choose_pixel_format_arb_1(bool stereoVisual, bool needAlpha); - void initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD); - HWND m_hWnd; HDC m_hDC; diff --git a/intern/ghost/intern/GHOST_DisplayManagerNULL.h b/intern/ghost/intern/GHOST_DisplayManagerNULL.h index ba72dcbe8dd..dbef4fafd8f 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerNULL.h +++ b/intern/ghost/intern/GHOST_DisplayManagerNULL.h @@ -8,38 +8,38 @@ #pragma once #include "GHOST_DisplayManager.h" -#include "GHOST_SystemNULL.h" +#include "GHOST_SystemHeadless.h" -class GHOST_SystemNULL; +class GHOST_SystemHeadless; class GHOST_DisplayManagerNULL : public GHOST_DisplayManager { public: - GHOST_DisplayManagerNULL(GHOST_SystemNULL *system) : GHOST_DisplayManager(), m_system(system) + GHOST_DisplayManagerNULL() : GHOST_DisplayManager() { /* nop */ } - GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const + GHOST_TSuccess getNumDisplays(uint8_t & /*numDisplays*/) const override { return GHOST_kFailure; } - GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const + GHOST_TSuccess getNumDisplaySettings(uint8_t /*display*/, + int32_t & /*numSettings*/) const override { return GHOST_kFailure; } - GHOST_TSuccess getDisplaySetting(uint8_t display, - int32_t index, - GHOST_DisplaySetting &setting) const + GHOST_TSuccess getDisplaySetting(uint8_t /*display*/, + int32_t /*index*/, + GHOST_DisplaySetting & /*setting*/) const override { return GHOST_kFailure; } - GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const + GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, + GHOST_DisplaySetting &setting) const override { return getDisplaySetting(display, int32_t(0), setting); } - GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting) + GHOST_TSuccess setCurrentDisplaySetting(uint8_t /*display*/, + const GHOST_DisplaySetting & /*setting*/) override { return GHOST_kSuccess; } - - private: - GHOST_SystemNULL *m_system; }; diff --git a/intern/ghost/intern/GHOST_DropTargetX11.cpp b/intern/ghost/intern/GHOST_DropTargetX11.cpp index 252a8bfd095..4da3c7c996d 100644 --- a/intern/ghost/intern/GHOST_DropTargetX11.cpp +++ b/intern/ghost/intern/GHOST_DropTargetX11.cpp @@ -7,6 +7,7 @@ #include "GHOST_DropTargetX11.h" #include "GHOST_Debug.h" +#include "GHOST_PathUtils.h" #include "GHOST_utildefines.h" #include <cassert> @@ -97,89 +98,10 @@ GHOST_DropTargetX11::~GHOST_DropTargetX11() } } -/* Based on: https://stackoverflow.com/a/2766963/432509 */ - -using DecodeState_e = enum DecodeState_e { - /** Searching for an ampersand to convert. */ - STATE_SEARCH = 0, - /** Convert the two proceeding characters from hex. */ - STATE_CONVERTING -}; - -void GHOST_DropTargetX11::UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn) -{ - unsigned int i; - unsigned int len = strlen(encodedIn); - DecodeState_e state = STATE_SEARCH; - int j; - unsigned int asciiCharacter; - char tempNumBuf[3] = {0}; - bool bothDigits = true; - - memset(decodedOut, 0, bufferSize); - - for (i = 0; i < len; ++i) { - switch (state) { - case STATE_SEARCH: - if (encodedIn[i] != '%') { - strncat(decodedOut, &encodedIn[i], 1); - assert((int)strlen(decodedOut) < bufferSize); - break; - } - - /* We are now converting */ - state = STATE_CONVERTING; - break; - - case STATE_CONVERTING: - bothDigits = true; - - /* Create a buffer to hold the hex. For example, if %20, this - * buffer would hold 20 (in ASCII) */ - memset(tempNumBuf, 0, sizeof(tempNumBuf)); - - /* Conversion complete (i.e. don't convert again next iter) */ - state = STATE_SEARCH; - - strncpy(tempNumBuf, &encodedIn[i], 2); - - /* Ensure both characters are hexadecimal */ - - for (j = 0; j < 2; ++j) { - if (!isxdigit(tempNumBuf[j])) { - bothDigits = false; - } - } - - if (!bothDigits) { - break; - } - /* Convert two hexadecimal characters into one character */ - sscanf(tempNumBuf, "%x", &asciiCharacter); - - /* Ensure we aren't going to overflow */ - assert((int)strlen(decodedOut) < bufferSize); - - /* Concatenate this character onto the output */ - strncat(decodedOut, (char *)&asciiCharacter, 1); - - /* Skip the next character */ - i++; - break; - } - } -} - char *GHOST_DropTargetX11::FileUrlDecode(char *fileUrl) { if (strncmp(fileUrl, "file://", 7) == 0) { - /* assume one character of encoded URL can be expanded to 4 chars max */ - int decodedSize = 4 * strlen(fileUrl) + 1; - char *decodedPath = (char *)malloc(decodedSize); - - UrlDecode(decodedPath, decodedSize, fileUrl + 7); - - return decodedPath; + return GHOST_URL_decode_alloc(fileUrl + 7); } return nullptr; diff --git a/intern/ghost/intern/GHOST_DropTargetX11.h b/intern/ghost/intern/GHOST_DropTargetX11.h index f0ef27697e1..db73ddff70f 100644 --- a/intern/ghost/intern/GHOST_DropTargetX11.h +++ b/intern/ghost/intern/GHOST_DropTargetX11.h @@ -65,14 +65,6 @@ class GHOST_DropTargetX11 { void *getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize); /** - * Decode URL (i.e. converts `file:///a%20b/test` to `file:///a b/test`) - * \param decodedOut: - buffer for decoded URL. - * \param bufferSize: - size of output buffer. - * \param encodedIn: - input encoded buffer to be decoded. - */ - void UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn); - - /** * Fully decode file URL (i.e. converts `file:///a%20b/test` to `/a b/test`) * \param fileUrl: - file path URL to be fully decoded. * \return decoded file path (result should be free-d). diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h index 0813378a819..1e1c428e2ae 100644 --- a/intern/ghost/intern/GHOST_Event.h +++ b/intern/ghost/intern/GHOST_Event.h @@ -22,7 +22,7 @@ class GHOST_Event : public GHOST_IEvent { * \param window: The generating window (or NULL if system event). */ GHOST_Event(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window) - : m_type(type), m_time(msec), m_window(window), m_data(NULL) + : m_type(type), m_time(msec), m_window(window), m_data(nullptr) { } diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp index 4f6a9531077..13eccf661f5 100644 --- a/intern/ghost/intern/GHOST_ISystem.cpp +++ b/intern/ghost/intern/GHOST_ISystem.cpp @@ -9,14 +9,14 @@ * Copyright (C) 2001 NaN Technologies B.V. */ +#include <stdexcept> + #include "GHOST_ISystem.h" +#include "GHOST_SystemHeadless.h" -#if defined(WITH_HEADLESS) -# include "GHOST_SystemNULL.h" -#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND) +#if defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND) # include "GHOST_SystemWayland.h" # include "GHOST_SystemX11.h" -# include <stdexcept> #elif defined(WITH_GHOST_X11) # include "GHOST_SystemX11.h" #elif defined(WITH_GHOST_WAYLAND) @@ -49,26 +49,50 @@ GHOST_TSuccess GHOST_ISystem::createSystem() #endif #if defined(WITH_HEADLESS) - m_system = new GHOST_SystemNULL(); + /* Pass. */ #elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND) /* Special case, try Wayland, fall back to X11. */ try { m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr; } catch (const std::runtime_error &) { - /* fallback to X11. */ delete m_system; m_system = nullptr; } if (!m_system) { - m_system = new GHOST_SystemX11(); + /* Try to fallback to X11. */ + try { + m_system = new GHOST_SystemX11(); + } + catch (const std::runtime_error &) { + delete m_system; + m_system = nullptr; + } } #elif defined(WITH_GHOST_X11) - m_system = new GHOST_SystemX11(); + try { + m_system = new GHOST_SystemX11(); + } + catch (const std::runtime_error &) { + delete m_system; + m_system = nullptr; + } #elif defined(WITH_GHOST_WAYLAND) - m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr; + try { + m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr; + } + catch (const std::runtime_error &) { + delete m_system; + m_system = nullptr; + } #elif defined(WITH_GHOST_SDL) - m_system = new GHOST_SystemSDL(); + try { + m_system = new GHOST_SystemSDL(); + } + catch (const std::runtime_error &) { + delete m_system; + m_system = nullptr; + } #elif defined(WIN32) m_system = new GHOST_SystemWin32(); #elif defined(__APPLE__) @@ -85,6 +109,30 @@ GHOST_TSuccess GHOST_ISystem::createSystem() return success; } +GHOST_TSuccess GHOST_ISystem::createSystemBackground() +{ + GHOST_TSuccess success; + if (!m_system) { +#if !defined(WITH_HEADLESS) + /* Try to create a off-screen render surface with the graphical systems. */ + success = createSystem(); + if (success) { + return success; + } + /* Try to fallback to headless mode if all else fails. */ +#endif + m_system = new GHOST_SystemHeadless(); + success = m_system != nullptr ? GHOST_kSuccess : GHOST_kFailure; + } + else { + success = GHOST_kFailure; + } + if (success) { + success = m_system->init(); + } + return success; +} + GHOST_TSuccess GHOST_ISystem::disposeSystem() { GHOST_TSuccess success = GHOST_kSuccess; diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h index 1246aa19a99..152b6b68026 100644 --- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h +++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h @@ -17,11 +17,8 @@ class GHOST_IXrGraphicsBinding { public: union { #if defined(WITH_GHOST_X11) -# if defined(WITH_GL_EGL) XrGraphicsBindingEGLMNDX egl; -# else XrGraphicsBindingOpenGLXlibKHR glx; -# endif #elif defined(WIN32) XrGraphicsBindingOpenGLWin32KHR wgl; XrGraphicsBindingD3D11KHR d3d11; diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp index d58fb90f63e..746e3532b03 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.cpp +++ b/intern/ghost/intern/GHOST_NDOFManager.cpp @@ -411,8 +411,9 @@ static bool nearHomePosition(GHOST_TEventNDOFMotionData *ndof, float threshold) bool GHOST_NDOFManager::sendMotionEvent() { - if (!m_motionEventPending) + if (!m_motionEventPending) { return false; + } m_motionEventPending = false; /* Any pending motion is handled right now. */ diff --git a/intern/ghost/intern/GHOST_Path-api.cpp b/intern/ghost/intern/GHOST_Path-api.cpp index 1b1c72d8a4b..58f36dc096d 100644 --- a/intern/ghost/intern/GHOST_Path-api.cpp +++ b/intern/ghost/intern/GHOST_Path-api.cpp @@ -49,10 +49,10 @@ const char *GHOST_getBinaryDir() return systemPaths ? systemPaths->getBinaryDir() : nullptr; } -void GHOST_addToSystemRecentFiles(const char *filename) +void GHOST_addToSystemRecentFiles(const char *filepath) { GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get(); if (systemPaths) { - systemPaths->addToSystemRecentFiles(filename); + systemPaths->addToSystemRecentFiles(filepath); } } diff --git a/intern/ghost/intern/GHOST_PathUtils.cpp b/intern/ghost/intern/GHOST_PathUtils.cpp new file mode 100644 index 00000000000..3b57480039a --- /dev/null +++ b/intern/ghost/intern/GHOST_PathUtils.cpp @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2010 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup GHOST + */ + +#include <cassert> +#include <cctype> +#include <cstdio> +#include <cstdlib> +#include <cstring> + +#include "GHOST_PathUtils.h" +#include "GHOST_Types.h" + +/* Based on: https://stackoverflow.com/a/2766963/432509 */ + +using DecodeState_e = enum DecodeState_e { + /** Searching for an ampersand to convert. */ + STATE_SEARCH = 0, + /** Convert the two proceeding characters from hex. */ + STATE_CONVERTING +}; + +void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src) +{ + const unsigned int buf_src_len = strlen(buf_src); + DecodeState_e state = STATE_SEARCH; + unsigned int ascii_character; + char temp_num_buf[3] = {0}; + + memset(buf_dst, 0, buf_dst_size); + + for (unsigned int i = 0; i < buf_src_len; i++) { + switch (state) { + case STATE_SEARCH: { + if (buf_src[i] != '%') { + strncat(buf_dst, &buf_src[i], 1); + assert((int)strlen(buf_dst) < buf_dst_size); + break; + } + + /* We are now converting. */ + state = STATE_CONVERTING; + break; + } + case STATE_CONVERTING: { + bool both_digits = true; + + /* Create a buffer to hold the hex. For example, if `%20`, + * this buffer would hold 20 (in ASCII). */ + memset(temp_num_buf, 0, sizeof(temp_num_buf)); + + /* Conversion complete (i.e. don't convert again next iteration). */ + state = STATE_SEARCH; + + strncpy(temp_num_buf, &buf_src[i], 2); + + /* Ensure both characters are hexadecimal. */ + for (int j = 0; j < 2; j++) { + if (!isxdigit(temp_num_buf[j])) { + both_digits = false; + } + } + + if (!both_digits) { + break; + } + /* Convert two hexadecimal characters into one character. */ + sscanf(temp_num_buf, "%x", &ascii_character); + + /* Ensure we aren't going to overflow. */ + assert((int)strlen(buf_dst) < buf_dst_size); + + /* Concatenate this character onto the output. */ + strncat(buf_dst, (char *)&ascii_character, 1); + + /* Skip the next character. */ + i++; + break; + } + } + } +} + +char *GHOST_URL_decode_alloc(const char *buf_src) +{ + /* Assume one character of encoded URL can be expanded to 4 chars max. */ + const size_t decoded_size_max = 4 * strlen(buf_src) + 1; + char *buf_dst = (char *)malloc(decoded_size_max); + GHOST_URL_decode(buf_dst, decoded_size_max, buf_src); + const size_t decoded_size = strlen(buf_dst) + 1; + if (decoded_size != decoded_size_max) { + char *buf_dst_trim = (char *)malloc(decoded_size); + memcpy(buf_dst_trim, buf_dst, decoded_size); + free(buf_dst); + buf_dst = buf_dst_trim; + } + return buf_dst; +} diff --git a/intern/ghost/intern/GHOST_PathUtils.h b/intern/ghost/intern/GHOST_PathUtils.h new file mode 100644 index 00000000000..26a31d1f5c6 --- /dev/null +++ b/intern/ghost/intern/GHOST_PathUtils.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2010 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup GHOST + */ + +#pragma once + +/** + * Decode URL (i.e. converts `file:///a%20b/test` to `file:///a b/test`) + * + * \param buf_dst: Buffer for decoded URL. + * \param buf_dst_maxlen: Size of output buffer. + * \param buf_src: Input encoded buffer to be decoded. + */ +void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src); +/** + * A version of #GHOST_URL_decode that allocates the string & returns it. + * + * \param buf_src: Input encoded buffer to be decoded. + * \return The decoded output buffer. + */ +char *GHOST_URL_decode_alloc(const char *buf_src); diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index cf04287af9f..bfb7c958048 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -110,8 +110,7 @@ bool GHOST_System::validWindow(GHOST_IWindow *window) GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window, - const bool stereoVisual, - const bool alphaBackground) + const bool stereoVisual) { GHOST_TSuccess success = GHOST_kFailure; GHOST_ASSERT(m_windowManager, "GHOST_System::beginFullScreen(): invalid window manager"); @@ -125,8 +124,7 @@ GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting &setting setting); if (success == GHOST_kSuccess) { // GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n"); - success = createFullScreenWindow( - (GHOST_Window **)window, setting, stereoVisual, alphaBackground); + success = createFullScreenWindow((GHOST_Window **)window, setting, stereoVisual); if (success == GHOST_kSuccess) { m_windowManager->beginFullScreen(*window, stereoVisual); } @@ -373,18 +371,13 @@ GHOST_TSuccess GHOST_System::exit() GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, - const bool stereoVisual, - const bool alphaBackground) + const bool stereoVisual) { GHOST_GLSettings glSettings = {0}; if (stereoVisual) { glSettings.flags |= GHOST_glStereoVisual; } - if (alphaBackground) { - glSettings.flags |= GHOST_glAlphaBackground; - } - /* NOTE: don't use #getCurrentDisplaySetting() because on X11 we may * be zoomed in and the desktop may be bigger than the viewport. */ GHOST_ASSERT(m_displayManager, diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index d5558be3444..8c51b3421b2 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -120,8 +120,7 @@ class GHOST_System : public GHOST_ISystem { */ GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window, - const bool stereoVisual, - const bool alphaBackground); + const bool stereoVisual); /** * Updates the resolution while in fullscreen mode. @@ -376,8 +375,7 @@ class GHOST_System : public GHOST_ISystem { */ GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, - const bool stereoVisual, - const bool alphaBackground = 0); + const bool stereoVisual); /** The display manager (platform dependent). */ GHOST_DisplayManager *m_displayManager; diff --git a/intern/ghost/intern/GHOST_SystemHeadless.h b/intern/ghost/intern/GHOST_SystemHeadless.h new file mode 100644 index 00000000000..dcf445420a4 --- /dev/null +++ b/intern/ghost/intern/GHOST_SystemHeadless.h @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup GHOST + * Declaration of GHOST_SystemHeadless class. + */ + +#pragma once + +#include "../GHOST_Types.h" +#include "GHOST_DisplayManagerNULL.h" +#include "GHOST_System.h" +#include "GHOST_WindowNULL.h" + +#ifdef __linux__ +# include "GHOST_ContextEGL.h" +#endif +#include "GHOST_ContextNone.h" + +class GHOST_WindowNULL; + +class GHOST_SystemHeadless : public GHOST_System { + public: + GHOST_SystemHeadless() : GHOST_System() + { /* nop */ + } + ~GHOST_SystemHeadless() override = default; + + bool processEvents(bool /*waitForEvent*/) override + { + return false; + } + int setConsoleWindowState(GHOST_TConsoleWindowState /*action*/) override + { + return 0; + } + GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys & /*keys*/) const override + { + return GHOST_kSuccess; + } + GHOST_TSuccess getButtons(GHOST_Buttons & /*buttons*/) const override + { + return GHOST_kSuccess; + } + char *getClipboard(bool /*selection*/) const override + { + return nullptr; + } + void putClipboard(const char * /*buffer*/, bool /*selection*/) const override + { /* nop */ + } + uint64_t getMilliSeconds() const override + { + return 0; + } + uint8_t getNumDisplays() const override + { + return uint8_t(1); + } + GHOST_TSuccess getCursorPosition(int32_t & /*x*/, int32_t & /*y*/) const override + { + return GHOST_kFailure; + } + GHOST_TSuccess setCursorPosition(int32_t /*x*/, int32_t /*y*/) override + { + return GHOST_kFailure; + } + void getMainDisplayDimensions(uint32_t & /*width*/, uint32_t & /*height*/) const override + { /* nop */ + } + void getAllDisplayDimensions(uint32_t & /*width*/, uint32_t & /*height*/) const override + { /* nop */ + } + GHOST_IContext *createOffscreenContext(GHOST_GLSettings /*glSettings*/) override + { +#ifdef __linux__ + GHOST_Context *context; + for (int minor = 6; minor >= 0; --minor) { + context = new GHOST_ContextEGL((GHOST_System *)this, + false, + EGLNativeWindowType(0), + EGLNativeDisplayType(EGL_DEFAULT_DISPLAY), + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + 4, + minor, + GHOST_OPENGL_EGL_CONTEXT_FLAGS, + GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, + EGL_OPENGL_API); + + if (context->initializeDrawingContext()) { + return context; + } + delete context; + context = nullptr; + } + + context = new GHOST_ContextEGL((GHOST_System *)this, + false, + EGLNativeWindowType(0), + EGLNativeDisplayType(EGL_DEFAULT_DISPLAY), + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + 3, + 3, + GHOST_OPENGL_EGL_CONTEXT_FLAGS, + GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, + EGL_OPENGL_API); + + if (context->initializeDrawingContext() != GHOST_kSuccess) { + delete context; + context = nullptr; + } + return context; +#else + return nullptr; +#endif + } + GHOST_TSuccess disposeContext(GHOST_IContext *context) override + { + delete context; + + return GHOST_kSuccess; + } + + GHOST_TSuccess init() override + { + GHOST_TSuccess success = GHOST_System::init(); + + if (success) { + m_displayManager = new GHOST_DisplayManagerNULL(); + + if (m_displayManager) { + return GHOST_kSuccess; + } + } + + return GHOST_kFailure; + } + + GHOST_IWindow *createWindow(const char *title, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type, + GHOST_GLSettings glSettings, + const bool /*exclusive*/, + const bool /*is_dialog*/, + const GHOST_IWindow *parentWindow) override + { + return new GHOST_WindowNULL(title, + left, + top, + width, + height, + state, + parentWindow, + type, + ((glSettings.flags & GHOST_glStereoVisual) != 0)); + } + + GHOST_IWindow *getWindowUnderCursor(int32_t /*x*/, int32_t /*y*/) override + { + return nullptr; + } +}; diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h deleted file mode 100644 index 644eb1ba0a5..00000000000 --- a/intern/ghost/intern/GHOST_SystemNULL.h +++ /dev/null @@ -1,122 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup GHOST - * Declaration of GHOST_SystemNULL class. - */ - -#pragma once - -#include "../GHOST_Types.h" -#include "GHOST_DisplayManagerNULL.h" -#include "GHOST_System.h" -#include "GHOST_WindowNULL.h" - -class GHOST_WindowNULL; - -class GHOST_SystemNULL : public GHOST_System { - public: - GHOST_SystemNULL() : GHOST_System() - { /* nop */ - } - ~GHOST_SystemNULL() - { /* nop */ - } - bool processEvents(bool waitForEvent) - { - return false; - } - int setConsoleWindowState(GHOST_TConsoleWindowState action) - { - return 0; - } - GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const - { - return GHOST_kSuccess; - } - GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const - { - return GHOST_kSuccess; - } - char *getClipboard(bool selection) const - { - return nullptr; - } - void putClipboard(const char *buffer, bool selection) const - { /* nop */ - } - uint64_t getMilliSeconds() const - { - return 0; - } - uint8_t getNumDisplays() const - { - return uint8_t(1); - } - GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const - { - return GHOST_kFailure; - } - GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) - { - return GHOST_kFailure; - } - void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const - { /* nop */ - } - void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const - { /* nop */ - } - GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) - { - return nullptr; - } - GHOST_TSuccess disposeContext(GHOST_IContext *context) - { - return GHOST_kFailure; - } - - GHOST_TSuccess init() - { - GHOST_TSuccess success = GHOST_System::init(); - - if (success) { - m_displayManager = new GHOST_DisplayManagerNULL(this); - - if (m_displayManager) { - return GHOST_kSuccess; - } - } - - return GHOST_kFailure; - } - - GHOST_IWindow *createWindow(const char *title, - int32_t left, - int32_t top, - uint32_t width, - uint32_t height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type, - GHOST_GLSettings glSettings, - const bool exclusive, - const bool is_dialog, - const GHOST_IWindow *parentWindow) - { - return new GHOST_WindowNULL(this, - title, - left, - top, - width, - height, - state, - parentWindow, - type, - ((glSettings.flags & GHOST_glStereoVisual) != 0)); - } - - GHOST_IWindow *getWindowUnderCursor(int32_t x, int32_t y) - { - return nullptr; - } -}; diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index d912b57f049..6d0b2b8aa55 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -5,6 +5,7 @@ */ #include <cassert> +#include <stdexcept> #include "GHOST_ContextSDL.h" #include "GHOST_SystemSDL.h" @@ -20,7 +21,7 @@ GHOST_SystemSDL::GHOST_SystemSDL() : GHOST_System() { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { - printf("Error initializing SDL: %s\n", SDL_GetError()); + throw std::runtime_error("Error initializing SDL: " + std::string(SDL_GetError())); } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index ebb52bf08cb..57b1a9bb434 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -11,18 +11,22 @@ #include "GHOST_EventDragnDrop.h" #include "GHOST_EventKey.h" #include "GHOST_EventWheel.h" +#include "GHOST_PathUtils.h" #include "GHOST_TimerManager.h" +#include "GHOST_WaylandUtils.h" #include "GHOST_WindowManager.h" #include "GHOST_utildefines.h" #include "GHOST_ContextEGL.h" +#ifdef WITH_INPUT_NDOF +# include "GHOST_NDOFManagerUnix.h" +#endif + #ifdef WITH_GHOST_WAYLAND_DYNLOAD # include <wayland_dynload_API.h> /* For `ghost_wl_dynload_libraries`. */ #endif -#include <EGL/egl.h> - #ifdef WITH_GHOST_WAYLAND_DYNLOAD # include <wayland_dynload_egl.h> #endif @@ -82,6 +86,10 @@ static void output_handle_done(void *data, struct wl_output *wl_output); static bool use_gnome_confine_hack = false; #endif +#define XKB_STATE_MODS_ALL \ + (enum xkb_state_component)(XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED | \ + XKB_STATE_MODS_LOCKED | XKB_STATE_MODS_EFFECTIVE) + /* -------------------------------------------------------------------- */ /** \name Inline Event Codes * @@ -306,6 +314,20 @@ struct input_t { */ struct xkb_state *xkb_state_empty_with_numlock = nullptr; + /** + * Cache result of `xkb_keymap_mod_get_index` + * so every time a modifier is accessed a string lookup isn't required. + * Be sure to check for #XKB_MOD_INVALID before using. + */ + struct { + xkb_mod_index_t shift; /* #XKB_MOD_NAME_SHIFT */ + xkb_mod_index_t caps; /* #XKB_MOD_NAME_CAPS */ + xkb_mod_index_t ctrl; /* #XKB_MOD_NAME_CTRL */ + xkb_mod_index_t alt; /* #XKB_MOD_NAME_ALT */ + xkb_mod_index_t num; /* #XKB_MOD_NAME_NUM */ + xkb_mod_index_t logo; /* #XKB_MOD_NAME_LOGO */ + } xkb_keymap_mod_index; + struct { /** Key repetition in character per second. */ int32_t rate = 0; @@ -1138,6 +1160,7 @@ static void data_device_handle_enter(void *data, input_t *input = static_cast<input_t *>(data); std::lock_guard lock{input->data_offer_dnd_mutex}; + delete input->data_offer_dnd; input->data_offer_dnd = static_cast<data_offer_t *>(wl_data_offer_get_user_data(id)); data_offer_t *data_offer = input->data_offer_dnd; @@ -1197,8 +1220,6 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat input_t *input = static_cast<input_t *>(data); std::lock_guard lock{input->data_offer_dnd_mutex}; - CLOG_INFO(LOG, 2, "drop"); - data_offer_t *data_offer = input->data_offer_dnd; const std::string mime_receive = *std::find_first_of(mime_preference_order.begin(), @@ -1206,6 +1227,8 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat data_offer->types.begin(), data_offer->types.end()); + CLOG_INFO(LOG, 2, "drop mime_recieve=%s", mime_receive.c_str()); + auto read_uris_fn = [](input_t *const input, data_offer_t *data_offer, wl_surface *surface, @@ -1214,9 +1237,15 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat const std::string data = read_pipe(data_offer, mime_receive, nullptr); + CLOG_INFO( + LOG, 2, "drop_read_uris mime_receive=%s, data=%s", mime_receive.c_str(), data.c_str()); + wl_data_offer_finish(data_offer->id); wl_data_offer_destroy(data_offer->id); + if (input->data_offer_dnd == data_offer) { + input->data_offer_dnd = nullptr; + } delete data_offer; data_offer = nullptr; @@ -1224,7 +1253,9 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat if (mime_receive == mime_text_uri) { static constexpr const char *file_proto = "file://"; - static constexpr const char *crlf = "\r\n"; + /* NOTE: some applications CRLF (`\r\n`) GTK3 for e.g. & others don't `pcmanfm-qt`. + * So support both, once `\n` is found, strip the preceding `\r` if found. */ + static constexpr const char *lf = "\n"; GHOST_WindowWayland *win = ghost_wl_surface_user_data(surface); std::vector<std::string> uris; @@ -1233,13 +1264,18 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat while (true) { pos = data.find(file_proto, pos); const size_t start = pos + sizeof(file_proto) - 1; - pos = data.find(crlf, pos); - const size_t end = pos; + pos = data.find(lf, pos); if (pos == std::string::npos) { break; } + /* Account for 'CRLF' case. */ + size_t end = pos; + if (data[end - 1] == '\r') { + end -= 1; + } uris.push_back(data.substr(start, end - start)); + CLOG_INFO(LOG, 2, "drop_read_uris pos=%zu, text_uri=\"%s\"", start, uris.back().c_str()); } GHOST_TStringArray *flist = static_cast<GHOST_TStringArray *>( @@ -1247,10 +1283,10 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat flist->count = int(uris.size()); flist->strings = static_cast<uint8_t **>(malloc(uris.size() * sizeof(uint8_t *))); for (size_t i = 0; i < uris.size(); i++) { - flist->strings[i] = static_cast<uint8_t *>(malloc((uris[i].size() + 1) * sizeof(uint8_t))); - memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1); + flist->strings[i] = (uint8_t *)GHOST_URL_decode_alloc(uris[i].c_str()); } + CLOG_INFO(LOG, 2, "drop_read_uris_fn file_count=%d", flist->count); const wl_fixed_t scale = win->scale(); system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(), GHOST_kEventDraggingDropDone, @@ -1263,12 +1299,13 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat else if (ELEM(mime_receive, mime_text_plain, mime_text_utf8)) { /* TODO: enable use of internal functions 'txt_insert_buf' and * 'text_update_edited' to behave like dropped text was pasted. */ + CLOG_INFO(LOG, 2, "drop_read_uris_fn (text_plain, text_utf8), unhandled!"); } wl_display_roundtrip(system->display()); }; /* Pass in `input->focus_dnd` instead of accessing it from `input` since the leave callback - * (#data_device_leave) will clear the value once this function starts. */ + * (#data_device_handle_leave) will clear the value once this function starts. */ std::thread read_thread(read_uris_fn, input, data_offer, input->focus_dnd, mime_receive); read_thread.detach(); } @@ -1288,6 +1325,7 @@ static void data_device_handle_selection(void *data, wl_data_offer_destroy(data_offer->id); delete data_offer; data_offer = nullptr; + input->data_offer_copy_paste = nullptr; } if (id == nullptr) { @@ -2086,6 +2124,13 @@ static void keyboard_handle_keymap(void *data, } } + input->xkb_keymap_mod_index.shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT); + input->xkb_keymap_mod_index.caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS); + input->xkb_keymap_mod_index.ctrl = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL); + input->xkb_keymap_mod_index.alt = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT); + input->xkb_keymap_mod_index.num = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM); + input->xkb_keymap_mod_index.logo = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_LOGO); + xkb_keymap_unref(keymap); } @@ -2099,7 +2144,7 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard * /*wl_keyboard*/, const uint32_t serial, struct wl_surface *surface, - struct wl_array * /*keys*/) + struct wl_array *keys) { if (!ghost_wl_surface_own(surface)) { CLOG_INFO(LOG, 2, "enter (skipped)"); @@ -2110,6 +2155,49 @@ static void keyboard_handle_enter(void *data, input_t *input = static_cast<input_t *>(data); input->keyboard.serial = serial; input->keyboard.wl_surface = surface; + + if (keys->size != 0) { + /* If there are any keys held when activating the window, + * modifiers will be compared against the input state, + * only enabling modifiers that were previously disabled. */ + + const xkb_mod_mask_t state = xkb_state_serialize_mods(input->xkb_state, XKB_STATE_MODS_ALL); + uint32_t *key; + WL_ARRAY_FOR_EACH (key, keys) { + const xkb_keycode_t key_code = *key + EVDEV_OFFSET; + const xkb_keysym_t sym = xkb_state_key_get_one_sym(input->xkb_state, key_code); + GHOST_TKey gkey = GHOST_kKeyUnknown; + +#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod))) +#define MOD_TEST_CASE(xkb_key, ghost_key, mod_index) \ + case xkb_key: \ + if (!MOD_TEST(state, input->xkb_keymap_mod_index.mod_index)) { \ + gkey = ghost_key; \ + } \ + break + + switch (sym) { + MOD_TEST_CASE(XKB_KEY_Shift_L, GHOST_kKeyLeftShift, shift); + MOD_TEST_CASE(XKB_KEY_Shift_R, GHOST_kKeyRightShift, shift); + MOD_TEST_CASE(XKB_KEY_Control_L, GHOST_kKeyLeftControl, ctrl); + MOD_TEST_CASE(XKB_KEY_Control_R, GHOST_kKeyRightControl, ctrl); + MOD_TEST_CASE(XKB_KEY_Alt_L, GHOST_kKeyLeftAlt, alt); + MOD_TEST_CASE(XKB_KEY_Alt_R, GHOST_kKeyRightAlt, alt); + MOD_TEST_CASE(XKB_KEY_Super_L, GHOST_kKeyOS, logo); + MOD_TEST_CASE(XKB_KEY_Super_R, GHOST_kKeyOS, logo); + } + +#undef MOD_TEST +#undef MOD_TEST_CASE + + if (gkey != GHOST_kKeyUnknown) { + GHOST_IWindow *win = ghost_wl_surface_user_data(surface); + GHOST_SystemWayland *system = input->system; + input->system->pushEvent( + new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyDown, win, gkey, false)); + } + } + } } /** @@ -2336,7 +2424,13 @@ static void keyboard_handle_modifiers(void *data, const uint32_t mods_locked, const uint32_t group) { - CLOG_INFO(LOG, 2, "modifiers"); + CLOG_INFO(LOG, + 2, + "modifiers (depressed=%u, latched=%u, locked=%u, group=%u)", + mods_depressed, + mods_latched, + mods_locked, + group); input_t *input = static_cast<input_t *>(data); xkb_state_update_mask(input->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); @@ -2473,7 +2567,7 @@ static void xdg_output_handle_logical_size(void *data, * done (we can't match exactly because fractional scaling can't be * detected otherwise), then override if necessary. */ if ((output->size_logical[0] == width) && (output->scale_fractional == wl_fixed_from_int(1))) { - GHOST_PRINT("xdg_output scale did not match, overriding with wl_output scale"); + GHOST_PRINT("xdg_output scale did not match, overriding with wl_output scale\n"); #ifdef USE_GNOME_CONFINE_HACK /* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue @@ -2898,9 +2992,36 @@ GHOST_SystemWayland::~GHOST_SystemWayland() display_destroy(d); } +GHOST_TSuccess GHOST_SystemWayland::init() +{ + GHOST_TSuccess success = GHOST_System::init(); + + if (success) { +#ifdef WITH_INPUT_NDOF + m_ndofManager = new GHOST_NDOFManagerUnix(*this); +#endif + return GHOST_kSuccess; + } + + return GHOST_kFailure; +} + bool GHOST_SystemWayland::processEvents(bool waitForEvent) { - const bool fired = getTimerManager()->fireTimers(getMilliSeconds()); + bool any_processed = false; + + if (getTimerManager()->fireTimers(getMilliSeconds())) { + any_processed = true; + } + +#ifdef WITH_INPUT_NDOF + if (static_cast<GHOST_NDOFManagerUnix *>(m_ndofManager)->processEvents()) { + /* As NDOF bypasses WAYLAND event handling, + * never wait for an event when an NDOF event was found. */ + waitForEvent = false; + any_processed = true; + } +#endif /* WITH_INPUT_NDOF */ if (waitForEvent) { wl_display_dispatch(d->display); @@ -2909,7 +3030,11 @@ bool GHOST_SystemWayland::processEvents(bool waitForEvent) wl_display_roundtrip(d->display); } - return fired || (getEventManager()->getNumEvents() > 0); + if ((getEventManager()->getNumEvents() > 0)) { + any_processed = true; + } + + return any_processed; } int GHOST_SystemWayland::setConsoleWindowState(GHOST_TConsoleWindowState /*action*/) @@ -2923,32 +3048,36 @@ GHOST_TSuccess GHOST_SystemWayland::getModifierKeys(GHOST_ModifierKeys &keys) co return GHOST_kFailure; } - static const xkb_state_component mods_all = xkb_state_component( - XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED | XKB_STATE_MODS_LOCKED | - XKB_STATE_MODS_EFFECTIVE); + input_t *input = d->inputs[0]; bool val; - /* NOTE: XKB doesn't seem to differentiate between left/right modifiers. */ + /* NOTE: XKB doesn't differentiate between left/right modifiers + * for it's internal modifier state storage. */ + const xkb_mod_mask_t state = xkb_state_serialize_mods(input->xkb_state, XKB_STATE_MODS_ALL); - val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_SHIFT, mods_all) == 1; +#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod))) + + val = MOD_TEST(state, input->xkb_keymap_mod_index.shift); keys.set(GHOST_kModifierKeyLeftShift, val); keys.set(GHOST_kModifierKeyRightShift, val); - val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_ALT, mods_all) == 1; + val = MOD_TEST(state, input->xkb_keymap_mod_index.alt); keys.set(GHOST_kModifierKeyLeftAlt, val); keys.set(GHOST_kModifierKeyRightAlt, val); - val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_CTRL, mods_all) == 1; + val = MOD_TEST(state, input->xkb_keymap_mod_index.ctrl); keys.set(GHOST_kModifierKeyLeftControl, val); keys.set(GHOST_kModifierKeyRightControl, val); - val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_LOGO, mods_all) == 1; + val = MOD_TEST(state, input->xkb_keymap_mod_index.logo); keys.set(GHOST_kModifierKeyOS, val); - val = xkb_state_mod_name_is_active(d->inputs[0]->xkb_state, XKB_MOD_NAME_NUM, mods_all) == 1; + val = MOD_TEST(state, input->xkb_keymap_mod_index.num); keys.set(GHOST_kModifierKeyNum, val); +#undef MOD_TEST + return GHOST_kSuccess; } diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index bdf5f2fc273..632f4bf28d8 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -93,6 +93,8 @@ class GHOST_SystemWayland : public GHOST_System { ~GHOST_SystemWayland() override; + GHOST_TSuccess init(); + bool processEvents(bool waitForEvent) override; int setConsoleWindowState(GHOST_TConsoleWindowState action) override; diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 7c07ea6cd64..ddbe8b67742 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -227,7 +227,7 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title, state, type, ((glSettings.flags & GHOST_glStereoVisual) != 0), - ((glSettings.flags & GHOST_glAlphaBackground) != 0), + false, (GHOST_WindowWin32 *)parentWindow, ((glSettings.flags & GHOST_glDebugContext) != 0), is_dialog); @@ -272,7 +272,7 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GLSettings glSet HDC mHDC = GetDC(wnd); HDC prev_hdc = wglGetCurrentDC(); HGLRC prev_context = wglGetCurrentContext(); -#if defined(WITH_GL_PROFILE_CORE) + for (int minor = 5; minor >= 0; --minor) { context = new GHOST_ContextWGL(false, true, @@ -310,29 +310,6 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GLSettings glSet return NULL; } -#elif defined(WITH_GL_PROFILE_COMPAT) - // ask for 2.1 context, driver gives any GL version >= 2.1 - // (hopefully the latest compatibility profile) - // 2.1 ignores the profile bit & is incompatible with core profile - context = new GHOST_ContextWGL(false, - true, - NULL, - NULL, - 0, // no profile bit - 2, - 1, - (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - return context; - } - else { - delete context; - } -#else -# error // must specify either core or compat at build time -#endif finished: wglMakeCurrent(prev_hdc, prev_context); return context; @@ -1122,6 +1099,12 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind system->getCursorPosition(x_screen, y_screen); if (window->getCursorGrabModeIsWarp()) { + /* WORKAROUND: + * Sometimes Windows ignores `SetCursorPos()` or `SendInput()` calls or the mouse event is + * outdate. Identify these cases by checking if the cursor is not yet within bounds. */ + static bool is_warping_x = false; + static bool is_warping_y = false; + int32_t x_new = x_screen; int32_t y_new = y_screen; int32_t x_accum, y_accum; @@ -1138,29 +1121,41 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { + system->setCursorPosition(x_new, y_new); /* wrap */ + + /* Do not update the accum values if we are an outdated or failed pos-warp event. */ + if (!is_warping_x) { + is_warping_x = x_new != x_screen; + if (is_warping_x) { + x_accum += (x_screen - x_new); + } + } + + if (!is_warping_y) { + is_warping_y = y_new != y_screen; + if (is_warping_y) { + y_accum += (y_screen - y_new); + } + } + window->setCursorGrabAccum(x_accum, y_accum); + /* When wrapping we don't need to add an event because the setCursorPosition call will cause * a new event after. */ - system->setCursorPosition(x_new, y_new); /* wrap */ - window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new)); - } - else { - return new GHOST_EventCursor(system->getMilliSeconds(), - GHOST_kEventCursorMove, - window, - x_screen + x_accum, - y_screen + y_accum, - GHOST_TABLET_DATA_NONE); + return NULL; } + + is_warping_x = false; + is_warping_y = false; + x_screen += x_accum; + y_screen += y_accum; } - else { - return new GHOST_EventCursor(system->getMilliSeconds(), - GHOST_kEventCursorMove, - window, - x_screen, - y_screen, - GHOST_TABLET_DATA_NONE); - } - return NULL; + + return new GHOST_EventCursor(system->getMilliSeconds(), + GHOST_kEventCursorMove, + window, + x_screen, + y_screen, + GHOST_TABLET_DATA_NONE); } void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam) diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 00cc5f3af8f..bb98c0de19b 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -33,12 +33,8 @@ #include "GHOST_Debug.h" -#if defined(WITH_GL_EGL) -# include "GHOST_ContextEGL.h" -# include <EGL/eglext.h> -#else -# include "GHOST_ContextGLX.h" -#endif +#include "GHOST_ContextEGL.h" +#include "GHOST_ContextGLX.h" #ifdef WITH_XF86KEYSYM # include <X11/XF86keysym.h> @@ -105,8 +101,7 @@ GHOST_SystemX11::GHOST_SystemX11() : GHOST_System(), m_xkb_descr(nullptr), m_sta m_display = XOpenDisplay(nullptr); if (!m_display) { - std::cerr << "Unable to open a display" << std::endl; - abort(); /* was return before, but this would just mean it will crash later */ + throw std::runtime_error("X11: Unable to open a display"); } #ifdef USE_X11_ERROR_HANDLERS @@ -235,10 +230,6 @@ GHOST_SystemX11::~GHOST_SystemX11() clearXInputDevices(); #endif /* WITH_X11_XINPUT */ -#ifdef WITH_GL_EGL - ::eglTerminate(::eglGetDisplay(m_display)); -#endif - if (m_xkb_descr) { XkbFreeKeyboard(m_xkb_descr, XkbAllComponentsMask, true); } @@ -287,7 +278,7 @@ uint8_t GHOST_SystemX11::getNumDisplays() const void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { if (m_display) { - /* NOTE(campbell): for this to work as documented, + /* NOTE(@campbellbarton): for this to work as documented, * we would need to use Xinerama check r54370 for code that did this, * we've since removed since its not worth the extra dependency. */ getAllDisplayDimensions(width, height); @@ -354,7 +345,6 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title, is_dialog, ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive, - ((glSettings.flags & GHOST_glAlphaBackground) != 0), (glSettings.flags & GHOST_glDebugContext) != 0); if (window) { @@ -375,6 +365,56 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title, return window; } +#ifdef USE_EGL +static GHOST_Context *create_egl_context( + GHOST_SystemX11 *system, Display *display, bool debug_context, int ver_major, int ver_minor) +{ + GHOST_Context *context; + context = new GHOST_ContextEGL(system, + false, + EGLNativeWindowType(nullptr), + EGLNativeDisplayType(display), + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + ver_major, + ver_minor, + GHOST_OPENGL_EGL_CONTEXT_FLAGS | + (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0), + GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, + EGL_OPENGL_API); + + if (context->initializeDrawingContext()) { + return context; + } + delete context; + + return nullptr; +} +#endif + +static GHOST_Context *create_glx_context(Display *display, + bool debug_context, + int ver_major, + int ver_minor) +{ + GHOST_Context *context; + context = new GHOST_ContextGLX(false, + (Window) nullptr, + display, + (GLXFBConfig) nullptr, + GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + ver_major, + ver_minor, + GHOST_OPENGL_GLX_CONTEXT_FLAGS | + (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) { + return context; + } + delete context; + + return nullptr; +} /** * Create a new off-screen context. * Never explicitly delete the context, use #disposeContext() instead. @@ -394,98 +434,33 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0; -#if defined(WITH_GL_PROFILE_CORE) - { - const char *version_major = (char *)glewGetString(GLEW_VERSION_MAJOR); - if (version_major != nullptr && version_major[0] == '1') { - fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n"); - abort(); - } - } -#endif - - const int profile_mask = -#ifdef WITH_GL_EGL -# if defined(WITH_GL_PROFILE_CORE) - EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT; -# elif defined(WITH_GL_PROFILE_COMPAT) - EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT; -# else -# error // must specify either core or compat at build time -# endif -#else -# if defined(WITH_GL_PROFILE_CORE) - GLX_CONTEXT_CORE_PROFILE_BIT_ARB; -# elif defined(WITH_GL_PROFILE_COMPAT) - GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; -# else -# error // must specify either core or compat at build time -# endif -#endif - GHOST_Context *context; +#ifdef USE_EGL + /* Try to initialize an EGL context. */ for (int minor = 5; minor >= 0; --minor) { -#if defined(WITH_GL_EGL) - context = new GHOST_ContextEGL(this, - false, - EGLNativeWindowType(nullptr), - EGLNativeDisplayType(m_display), - profile_mask, - 4, - minor, - GHOST_OPENGL_EGL_CONTEXT_FLAGS | - (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0), - GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, - EGL_OPENGL_API); -#else - context = new GHOST_ContextGLX(false, - (Window) nullptr, - m_display, - (GLXFBConfig) nullptr, - profile_mask, - 4, - minor, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | - (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); -#endif - - if (context->initializeDrawingContext()) { + context = create_egl_context(this, m_display, debug_context, 4, minor); + if (context != nullptr) { return context; } - delete context; + } + context = create_egl_context(this, m_display, debug_context, 3, 3); + if (context != nullptr) { + return context; } -#if defined(WITH_GL_EGL) - context = new GHOST_ContextEGL(this, - false, - EGLNativeWindowType(nullptr), - EGLNativeDisplayType(m_display), - profile_mask, - 3, - 3, - GHOST_OPENGL_EGL_CONTEXT_FLAGS | - (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0), - GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, - EGL_OPENGL_API); -#else - context = new GHOST_ContextGLX(false, - (Window) nullptr, - m_display, - (GLXFBConfig) nullptr, - profile_mask, - 3, - 3, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | - (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); + /* EGL initialization failed, try to fallback to a GLX context. */ #endif - - if (context->initializeDrawingContext()) { + for (int minor = 5; minor >= 0; --minor) { + context = create_glx_context(m_display, debug_context, 4, minor); + if (context != nullptr) { + return context; + } + } + context = create_glx_context(m_display, debug_context, 3, 3); + if (context != nullptr) { return context; } - delete context; return nullptr; } @@ -514,8 +489,9 @@ static void destroyIMCallback(XIM /*xim*/, XPointer ptr, XPointer /*data*/) bool GHOST_SystemX11::openX11_IM() { - if (!m_display) + if (!m_display) { return false; + } /* set locale modifiers such as `@im=ibus` specified by XMODIFIERS. */ XSetLocaleModifiers(""); @@ -585,7 +561,7 @@ struct init_timestamp_data { Time timestamp; }; -static Bool init_timestamp_scanner(Display *, XEvent *event, XPointer arg) +static Bool init_timestamp_scanner(Display * /*display*/, XEvent *event, XPointer arg) { init_timestamp_data *data = reinterpret_cast<init_timestamp_data *>(arg); switch (event->type) { @@ -673,11 +649,12 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent) GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window); if (window && !window->getX11_XIC() && window->createX11_XIC()) { GHOST_PRINT("XIM input context created\n"); - if (xevent.type == KeyPress) + if (xevent.type == KeyPress) { /* we can assume the window has input focus * here, because key events are received only * when the window is focused. */ XSetICFocus(window->getX11_XIC()); + } } } } @@ -1321,10 +1298,12 @@ void GHOST_SystemX11::processEvent(XEvent *xe) #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) XIC xic = window->getX11_XIC(); if (xic) { - if (xe->type == FocusIn) + if (xe->type == FocusIn) { XSetICFocus(xic); - else + } + else { XUnsetICFocus(xic); + } } #endif @@ -2381,10 +2360,11 @@ class DialogData { /* Is the mouse inside the given button */ bool isInsideButton(XEvent &e, uint button_num) { - return ((e.xmotion.y > height - padding_y - button_height) && - (e.xmotion.y < height - padding_y) && - (e.xmotion.x > width - (padding_x + button_width) * button_num) && - (e.xmotion.x < width - padding_x - (padding_x + button_width) * (button_num - 1))); + return ( + (e.xmotion.y > (int)(height - padding_y - button_height)) && + (e.xmotion.y < (int)(height - padding_y)) && + (e.xmotion.x > (int)(width - (padding_x + button_width) * button_num)) && + (e.xmotion.x < (int)(width - padding_x - (padding_x + button_width) * (button_num - 1)))); } }; diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp index 504cdbfb6c8..e54c2515029 100644 --- a/intern/ghost/intern/GHOST_TimerManager.cpp +++ b/intern/ghost/intern/GHOST_TimerManager.cpp @@ -71,10 +71,11 @@ uint64_t GHOST_TimerManager::nextFireTime() TTimerVector::iterator iter; for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) { - uint64_t next = (*iter)->getNext(); + const uint64_t next = (*iter)->getNext(); - if (next < smallest) + if (next < smallest) { smallest = next; + } } return smallest; @@ -86,8 +87,9 @@ bool GHOST_TimerManager::fireTimers(uint64_t time) bool anyProcessed = false; for (iter = m_timers.begin(); iter != m_timers.end(); ++iter) { - if (fireTimer(time, *iter)) + if (fireTimer(time, *iter)) { anyProcessed = true; + } } return anyProcessed; @@ -113,9 +115,7 @@ bool GHOST_TimerManager::fireTimer(uint64_t time, GHOST_TimerTask *task) return true; } - else { - return false; - } + return false; } void GHOST_TimerManager::disposeTimers() diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h index 090a84d1f14..4458a107190 100644 --- a/intern/ghost/intern/GHOST_TimerManager.h +++ b/intern/ghost/intern/GHOST_TimerManager.h @@ -87,7 +87,7 @@ class GHOST_TimerManager { */ void disposeTimers(); - typedef std::vector<GHOST_TimerTask *> TTimerVector; + using TTimerVector = std::vector<GHOST_TimerTask *>; /** The list with event consumers. */ TTimerVector m_timers; diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h index 01b50251d69..f9c0a593d5f 100644 --- a/intern/ghost/intern/GHOST_WindowNULL.h +++ b/intern/ghost/intern/GHOST_WindowNULL.h @@ -11,32 +11,31 @@ #include <map> -class GHOST_SystemNULL; +class GHOST_SystemHeadless; class GHOST_WindowNULL : public GHOST_Window { public: - GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor) + GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor /*cursorShape*/) override { return GHOST_kSuccess; } - GHOST_WindowNULL(GHOST_SystemNULL *system, - const char *title, - int32_t left, - int32_t top, + GHOST_WindowNULL(const char *title, + int32_t /*left*/, + int32_t /*top*/, uint32_t width, uint32_t height, GHOST_TWindowState state, - const GHOST_IWindow *parentWindow, - GHOST_TDrawingContextType type, + const GHOST_IWindow * /*parentWindow*/, + GHOST_TDrawingContextType /*type*/, const bool stereoVisual) - : GHOST_Window(width, height, state, stereoVisual, false), m_system(system) + : GHOST_Window(width, height, state, stereoVisual, false) { setTitle(title); } protected: - GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type) + GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType /*type*/) { return GHOST_kSuccess; } @@ -44,114 +43,111 @@ class GHOST_WindowNULL : public GHOST_Window { { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) + GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/) override { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) + GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor /*shape*/) override { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, - uint8_t *mask, - int sizex, - int sizey, - int hotX, - int hotY, - bool canInvertColor) + GHOST_TSuccess setWindowCustomCursorShape(uint8_t * /*bitmap*/, + uint8_t * /*mask*/, + int /*sizex*/, + int /*sizey*/, + int /*hotX*/, + int /*hotY*/, + bool /*canInvertColor*/) override { return GHOST_kSuccess; } - bool getValid() const + bool getValid() const override { return true; } - void setTitle(const char *title) + void setTitle(const char * /*title*/) override { /* nothing */ } - std::string getTitle() const + std::string getTitle() const override { return "untitled"; } - void getWindowBounds(GHOST_Rect &bounds) const + void getWindowBounds(GHOST_Rect &bounds) const override { getClientBounds(bounds); } - void getClientBounds(GHOST_Rect &bounds) const + void getClientBounds(GHOST_Rect & /*bounds*/) const override { /* nothing */ } - GHOST_TSuccess setClientWidth(uint32_t width) + GHOST_TSuccess setClientWidth(uint32_t /*width*/) override { return GHOST_kFailure; } - GHOST_TSuccess setClientHeight(uint32_t height) + GHOST_TSuccess setClientHeight(uint32_t /*height*/) override { return GHOST_kFailure; } - GHOST_TSuccess setClientSize(uint32_t width, uint32_t height) + GHOST_TSuccess setClientSize(uint32_t /*width*/, uint32_t /*height*/) override { return GHOST_kFailure; } - void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const + void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const override { outX = inX; outY = inY; } - void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const + void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const override { outX = inX; outY = inY; } - GHOST_TSuccess swapBuffers() + GHOST_TSuccess swapBuffers() override { return GHOST_kFailure; } - GHOST_TSuccess activateDrawingContext() + GHOST_TSuccess activateDrawingContext() override { return GHOST_kFailure; } - ~GHOST_WindowNULL() - { /* nothing */ - } - GHOST_TSuccess setWindowCursorVisibility(bool visible) + ~GHOST_WindowNULL() override = default; + + GHOST_TSuccess setWindowCursorVisibility(bool /*visible*/) override { return GHOST_kSuccess; } - GHOST_TSuccess setState(GHOST_TWindowState state) + GHOST_TSuccess setState(GHOST_TWindowState /*state*/) override { return GHOST_kSuccess; } - GHOST_TWindowState getState() const + GHOST_TWindowState getState() const override { return GHOST_kWindowStateNormal; } - GHOST_TSuccess invalidate() + GHOST_TSuccess invalidate() override { return GHOST_kSuccess; } - GHOST_TSuccess setOrder(GHOST_TWindowOrder order) + GHOST_TSuccess setOrder(GHOST_TWindowOrder /*order*/) override { return GHOST_kSuccess; } - GHOST_TSuccess beginFullScreen() const + GHOST_TSuccess beginFullScreen() const override { return GHOST_kSuccess; } - GHOST_TSuccess endFullScreen() const + GHOST_TSuccess endFullScreen() const override { return GHOST_kSuccess; } private: - GHOST_SystemNULL *m_system; - /** * \param type: The type of rendering context create. * \return Indication of success. */ - GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) + GHOST_Context *newDrawingContext(GHOST_TDrawingContextType /*type*/) override { return nullptr; } diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp index 09192d989e4..59dc80cf7e6 100644 --- a/intern/ghost/intern/GHOST_WindowSDL.cpp +++ b/intern/ghost/intern/GHOST_WindowSDL.cpp @@ -6,7 +6,6 @@ #include "GHOST_WindowSDL.h" #include "SDL_mouse.h" -#include "glew-mx.h" #include "GHOST_ContextSDL.h" diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 2e17454d24f..20ab71ac95a 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -580,7 +580,6 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty if (type == GHOST_kDrawingContextTypeOpenGL) { GHOST_Context *context; -#if defined(WITH_GL_PROFILE_CORE) /* - AMD and Intel give us exactly this version * - NVIDIA gives at least this version <-- desired behavior * So we ask for 4.5, 4.4 ... 3.3 in descending order @@ -619,30 +618,6 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty } return context; - -#elif defined(WITH_GL_PROFILE_COMPAT) - // ask for 2.1 context, driver gives any GL version >= 2.1 - // (hopefully the latest compatibility profile) - // 2.1 ignores the profile bit & is incompatible with core profile - context = new GHOST_ContextWGL(m_wantStereoVisual, - m_wantAlphaBackground, - m_hWnd, - m_hDC, - 0, // no profile bit - 2, - 1, - (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - - if (context->initializeDrawingContext()) { - return context; - } - else { - delete context; - } -#else -# error // must specify either core or compat at build time -#endif } else if (type == GHOST_kDrawingContextTypeD3D) { GHOST_Context *context; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 2276e90387b..0b2617c1b9e 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -10,9 +10,7 @@ #include <X11/Xmd.h> #include <X11/Xutil.h> #include <X11/cursorfont.h> -#ifdef WITH_X11_ALPHA -# include <X11/extensions/Xrender.h> -#endif + #include "GHOST_Debug.h" #include "GHOST_IconX11.h" #include "GHOST_SystemX11.h" @@ -23,12 +21,8 @@ # include "GHOST_DropTargetX11.h" #endif -#ifdef WITH_GL_EGL -# include "GHOST_ContextEGL.h" -# include <EGL/eglext.h> -#else -# include "GHOST_ContextGLX.h" -#endif +#include "GHOST_ContextEGL.h" +#include "GHOST_ContextGLX.h" /* for XIWarpPointer */ #ifdef WITH_X11_XINPUT @@ -88,9 +82,7 @@ enum { #define _NET_WM_STATE_ADD 1 // #define _NET_WM_STATE_TOGGLE 2 // UNUSED -#ifdef WITH_GL_EGL - -static XVisualInfo *x11_visualinfo_from_egl(Display *display) +static XVisualInfo *get_x11_visualinfo(Display *display) { int num_visuals; XVisualInfo vinfo_template; @@ -98,103 +90,6 @@ static XVisualInfo *x11_visualinfo_from_egl(Display *display) return XGetVisualInfo(display, VisualScreenMask, &vinfo_template, &num_visuals); } -#else - -static XVisualInfo *x11_visualinfo_from_glx(Display *display, - bool stereoVisual, - bool needAlpha, - GLXFBConfig *fbconfig) -{ - int glx_major, glx_minor, glx_version; /* GLX version: major.minor */ - int glx_attribs[64]; - - *fbconfig = nullptr; - - /* Set up the minimum attributes that we require and see if - * X can find us a visual matching those requirements. */ - - if (!glXQueryVersion(display, &glx_major, &glx_minor)) { - fprintf(stderr, - "%s:%d: X11 glXQueryVersion() failed, " - "verify working openGL system!\n", - __FILE__, - __LINE__); - - return nullptr; - } - glx_version = glx_major * 100 + glx_minor; -# ifndef WITH_X11_ALPHA - (void)glx_version; -# endif - -# ifdef WITH_X11_ALPHA - if (needAlpha && glx_version >= 103 && - (glXChooseFBConfig || (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB( - (const GLubyte *)"glXChooseFBConfig")) != nullptr) && - (glXGetVisualFromFBConfig || - (glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddressARB( - (const GLubyte *)"glXGetVisualFromFBConfig")) != nullptr)) { - - GHOST_X11_GL_GetAttributes(glx_attribs, 64, stereoVisual, needAlpha, true); - - int nbfbconfig; - GLXFBConfig *fbconfigs = glXChooseFBConfig( - display, DefaultScreen(display), glx_attribs, &nbfbconfig); - - /* Any sample level or even zero, which means oversampling disabled, is good - * but we need a valid visual to continue */ - if (nbfbconfig > 0) { - /* take a frame buffer config that has alpha cap */ - for (int i = 0; i < nbfbconfig; i++) { - XVisualInfo *visual = (XVisualInfo *)glXGetVisualFromFBConfig(display, fbconfigs[i]); - if (!visual) - continue; - /* if we don't need a alpha background, the first config will do, otherwise - * test the alphaMask as it won't necessarily be present */ - if (needAlpha) { - XRenderPictFormat *pict_format = XRenderFindVisualFormat(display, visual->visual); - if (!pict_format) - continue; - if (pict_format->direct.alphaMask <= 0) - continue; - } - - *fbconfig = fbconfigs[i]; - XFree(fbconfigs); - - return visual; - } - - XFree(fbconfigs); - } - } - else -# endif - { - /* legacy, don't use extension */ - GHOST_X11_GL_GetAttributes(glx_attribs, 64, stereoVisual, needAlpha, false); - - XVisualInfo *visual = glXChooseVisual(display, DefaultScreen(display), glx_attribs); - - /* Any sample level or even zero, which means oversampling disabled, is good - * but we need a valid visual to continue */ - if (visual != nullptr) { - return visual; - } - } - - /* All options exhausted, cannot continue */ - fprintf(stderr, - "%s:%d: X11 glXChooseVisual() failed, " - "verify working openGL system!\n", - __FILE__, - __LINE__); - - return nullptr; -} - -#endif // WITH_GL_EGL - GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system, Display *display, const char *title, @@ -208,7 +103,6 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system, const bool is_dialog, const bool stereoVisual, const bool exclusive, - const bool alphaBackground, const bool is_debug) : GHOST_Window(width, height, state, stereoVisual, exclusive), m_display(display), @@ -232,13 +126,7 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system, m_is_debug_context(is_debug) { if (type == GHOST_kDrawingContextTypeOpenGL) { -#ifdef WITH_GL_EGL - m_visualInfo = x11_visualinfo_from_egl(m_display); - (void)alphaBackground; -#else - m_visualInfo = x11_visualinfo_from_glx( - m_display, stereoVisual, alphaBackground, (GLXFBConfig *)&m_fbconfig); -#endif + m_visualInfo = get_x11_visualinfo(m_display); } else { XVisualInfo tmp = {nullptr}; @@ -487,8 +375,9 @@ static Bool destroyICCallback(XIC /*xic*/, XPointer ptr, XPointer /*data*/) bool GHOST_WindowX11::createX11_XIC() { XIM xim = m_system->getX11_XIM(); - if (!xim) + if (!xim) { return false; + } XICCallback destroy; destroy.callback = (XICProc)destroyICCallback; @@ -536,17 +425,21 @@ void GHOST_WindowX11::refreshXInputDevices() XEventClass ev; DeviceMotionNotify(xtablet.Device, xtablet.MotionEvent, ev); - if (ev) + if (ev) { xevents.push_back(ev); + } DeviceButtonPress(xtablet.Device, xtablet.PressEvent, ev); - if (ev) + if (ev) { xevents.push_back(ev); + } ProximityIn(xtablet.Device, xtablet.ProxInEvent, ev); - if (ev) + if (ev) { xevents.push_back(ev); + } ProximityOut(xtablet.Device, xtablet.ProxOutEvent, ev); - if (ev) + if (ev) { xevents.push_back(ev); + } } XSelectExtensionEvent(m_display, m_window, xevents.data(), (int)xevents.size()); @@ -1285,6 +1178,65 @@ GHOST_WindowX11::~GHOST_WindowX11() } } +#ifdef USE_EGL +static GHOST_Context *create_egl_context(GHOST_SystemX11 *system, + Window window, + Display *display, + bool want_stereo, + bool debug_context, + int ver_major, + int ver_minor) +{ + GHOST_Context *context; + context = new GHOST_ContextEGL(system, + want_stereo, + EGLNativeWindowType(window), + EGLNativeDisplayType(display), + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + ver_major, + ver_minor, + GHOST_OPENGL_EGL_CONTEXT_FLAGS | + (debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0), + GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, + EGL_OPENGL_API); + + if (context->initializeDrawingContext()) { + return context; + } + delete context; + + return nullptr; +} +#endif + +static GHOST_Context *create_glx_context(Window window, + Display *display, + GLXFBConfig fbconfig, + bool want_stereo, + bool debug_context, + int ver_major, + int ver_minor) +{ + GHOST_Context *context; + context = new GHOST_ContextGLX(want_stereo, + window, + display, + fbconfig, + GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + ver_major, + ver_minor, + GHOST_OPENGL_GLX_CONTEXT_FLAGS | + (debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), + GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); + + if (context->initializeDrawingContext()) { + return context; + } + delete context; + + return nullptr; +} + GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type) { if (type == GHOST_kDrawingContextTypeOpenGL) { @@ -1299,99 +1251,48 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type * - Try 3.3 core profile * - No fall-backs. */ -#if defined(WITH_GL_PROFILE_CORE) - { - const char *version_major = (char *)glewGetString(GLEW_VERSION_MAJOR); - if (version_major != nullptr && version_major[0] == '1') { - fprintf(stderr, "Error: GLEW version 2.0 and above is required.\n"); - abort(); - } - } -#endif - - const int profile_mask = -#ifdef WITH_GL_EGL -# if defined(WITH_GL_PROFILE_CORE) - EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT; -# elif defined(WITH_GL_PROFILE_COMPAT) - EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT; -# else -# error // must specify either core or compat at build time -# endif -#else -# if defined(WITH_GL_PROFILE_CORE) - GLX_CONTEXT_CORE_PROFILE_BIT_ARB; -# elif defined(WITH_GL_PROFILE_COMPAT) - GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; -# else -# error // must specify either core or compat at build time -# endif -#endif - GHOST_Context *context; +#ifdef USE_EGL + /* Try to initialize an EGL context. */ for (int minor = 5; minor >= 0; --minor) { -#ifdef WITH_GL_EGL - context = new GHOST_ContextEGL( - this->m_system, - m_wantStereoVisual, - EGLNativeWindowType(m_window), - EGLNativeDisplayType(m_display), - profile_mask, - 4, - minor, - GHOST_OPENGL_EGL_CONTEXT_FLAGS | - (m_is_debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0), - GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, - EGL_OPENGL_API); -#else - context = new GHOST_ContextGLX(m_wantStereoVisual, - m_window, - m_display, - (GLXFBConfig)m_fbconfig, - profile_mask, - 4, - minor, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | - (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); -#endif - - if (context->initializeDrawingContext()) { + context = create_egl_context( + this->m_system, m_window, m_display, m_wantStereoVisual, m_is_debug_context, 4, minor); + if (context != nullptr) { return context; } - delete context; } -#ifdef WITH_GL_EGL - context = new GHOST_ContextEGL(this->m_system, - m_wantStereoVisual, - EGLNativeWindowType(m_window), - EGLNativeDisplayType(m_display), - profile_mask, - 3, - 3, - GHOST_OPENGL_EGL_CONTEXT_FLAGS | - (m_is_debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0), - GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, - EGL_OPENGL_API); -#else - context = new GHOST_ContextGLX(m_wantStereoVisual, - m_window, + context = create_egl_context( + this->m_system, m_window, m_display, m_wantStereoVisual, m_is_debug_context, 3, 3); + if (context != nullptr) { + return context; + } + + /* EGL initialization failed, try to fallback to a GLX context. */ +#endif + for (int minor = 5; minor >= 0; --minor) { + context = create_glx_context(m_window, m_display, (GLXFBConfig)m_fbconfig, - profile_mask, - 3, - 3, - GHOST_OPENGL_GLX_CONTEXT_FLAGS | - (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), - GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY); -#endif - - if (context->initializeDrawingContext()) { + m_wantStereoVisual, + m_is_debug_context, + 4, + minor); + if (context != nullptr) { + return context; + } + } + context = create_glx_context(m_window, + m_display, + (GLXFBConfig)m_fbconfig, + m_wantStereoVisual, + m_is_debug_context, + 3, + 3); + if (context != nullptr) { return context; } - delete context; /* Ugly, but we get crashes unless a whole bunch of systems are patched. */ fprintf(stderr, "Error! Unsupported graphics card or driver.\n"); diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index ac4edd83549..c7a6b5e7357 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -47,7 +47,6 @@ class GHOST_WindowX11 : public GHOST_Window { * \param parentWindow: Parent (embedder) window. * \param type: The type of drawing context installed in this window. * \param stereoVisual: Stereo visual for quad buffered stereo. - * \param alphaBackground: Enable alpha blending of window with display background. */ GHOST_WindowX11(GHOST_SystemX11 *system, Display *display, @@ -62,7 +61,6 @@ class GHOST_WindowX11 : public GHOST_Window { const bool is_dialog = false, const bool stereoVisual = false, const bool exclusive = false, - const bool alphaBackground = false, const bool is_debug = false); bool getValid() const; diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp index 2ac3d9ec2a5..413e2670750 100644 --- a/intern/ghost/intern/GHOST_XrContext.cpp +++ b/intern/ghost/intern/GHOST_XrContext.cpp @@ -436,9 +436,11 @@ void GHOST_XrContext::getExtensionsToEnable( r_ext_names.push_back(gpu_binding); } -#if defined(WITH_GHOST_X11) && defined(WITH_GL_EGL) - assert(openxr_extension_is_available(m_oxr->extensions, XR_MNDX_EGL_ENABLE_EXTENSION_NAME)); - r_ext_names.push_back(XR_MNDX_EGL_ENABLE_EXTENSION_NAME); +#if defined(WITH_GHOST_X11) + if (openxr_extension_is_available(m_oxr->extensions, XR_MNDX_EGL_ENABLE_EXTENSION_NAME)) { + /* Use EGL if that backend is available. */ + r_ext_names.push_back(XR_MNDX_EGL_ENABLE_EXTENSION_NAME); + } #endif for (const std::string_view &ext : try_ext) { diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp index aa230bf8deb..267d19dcecb 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp +++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp @@ -8,17 +8,16 @@ #include <list> #include <sstream> -#if defined(WITH_GL_EGL) +#if defined(WITH_GHOST_X11) # include "GHOST_ContextEGL.h" -# if defined(WITH_GHOST_X11) -# include "GHOST_SystemX11.h" -# endif -# if defined(WITH_GHOST_WAYLAND) -# include "GHOST_SystemWayland.h" -# endif -#elif defined(WITH_GHOST_X11) # include "GHOST_ContextGLX.h" -#elif defined(WIN32) +# include "GHOST_SystemX11.h" +#endif +#if defined(WITH_GHOST_WAYLAND) +# include "GHOST_ContextEGL.h" +# include "GHOST_SystemWayland.h" +#endif +#if defined(WIN32) # include "GHOST_ContextD3D.h" # include "GHOST_ContextWGL.h" # include "GHOST_SystemWin32.h" @@ -61,19 +60,30 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { XrSystemId system_id, std::string *r_requirement_info) const override { -#if defined(WITH_GL_EGL) - GHOST_ContextEGL &ctx_gl = static_cast<GHOST_ContextEGL &>(ghost_ctx); -#elif defined(WITH_GHOST_X11) - GHOST_ContextGLX &ctx_gl = static_cast<GHOST_ContextGLX &>(ghost_ctx); -#else + int gl_major_version, gl_minor_version; +#if defined(WIN32) GHOST_ContextWGL &ctx_gl = static_cast<GHOST_ContextWGL &>(ghost_ctx); + gl_major_version = ctx_gl.m_contextMajorVersion; + gl_minor_version = ctx_gl.m_contextMinorVersion; +#elif defined(WITH_GHOST_X11) || defined(WITH_GHOST_WAYLAND) + if (dynamic_cast<GHOST_ContextEGL *>(&ghost_ctx)) { + GHOST_ContextEGL &ctx_gl = static_cast<GHOST_ContextEGL &>(ghost_ctx); + gl_major_version = ctx_gl.m_contextMajorVersion; + gl_minor_version = ctx_gl.m_contextMinorVersion; + } +# if defined(WITH_GHOST_X11) + else { + GHOST_ContextGLX &ctx_gl = static_cast<GHOST_ContextGLX &>(ghost_ctx); + gl_major_version = ctx_gl.m_contextMajorVersion; + gl_minor_version = ctx_gl.m_contextMinorVersion; + } +# endif #endif static PFN_xrGetOpenGLGraphicsRequirementsKHR s_xrGetOpenGLGraphicsRequirementsKHR_fn = nullptr; // static XrInstance s_instance = XR_NULL_HANDLE; XrGraphicsRequirementsOpenGLKHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR}; - const XrVersion gl_version = XR_MAKE_VERSION( - ctx_gl.m_contextMajorVersion, ctx_gl.m_contextMinorVersion, 0); + const XrVersion gl_version = XR_MAKE_VERSION(gl_major_version, gl_minor_version, 0); /* Although it would seem reasonable that the proc address would not change if the instance was * the same, in testing, repeated calls to #xrGetInstanceProcAddress() with the same instance @@ -112,30 +122,41 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { void initFromGhostContext(GHOST_Context &ghost_ctx) override { -#if defined(WITH_GHOST_X11) -# if defined(WITH_GL_EGL) - GHOST_ContextEGL &ctx_egl = static_cast<GHOST_ContextEGL &>(ghost_ctx); - - if (dynamic_cast<const GHOST_SystemX11 *const>(ctx_egl.m_system)) { - oxr_binding.egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX; - oxr_binding.egl.getProcAddress = eglGetProcAddress; - oxr_binding.egl.display = ctx_egl.getDisplay(); - oxr_binding.egl.config = ctx_egl.getConfig(); - oxr_binding.egl.context = ctx_egl.getContext(); +#if defined(WITH_GHOST_X11) || defined(WITH_GHOST_WAYLAND) + if (dynamic_cast<GHOST_ContextEGL *>(&ghost_ctx)) { + GHOST_ContextEGL &ctx_egl = static_cast<GHOST_ContextEGL &>(ghost_ctx); + +# if defined(WITH_GHOST_WAYLAND) + if (dynamic_cast<const GHOST_SystemWayland *const>(ctx_egl.m_system)) { + oxr_binding.wl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR; + oxr_binding.wl.display = (struct wl_display *)ctx_egl.m_nativeDisplay; + } + else +# endif +# if defined(WITH_GHOST_X11) + { + /* SystemX11. */ + oxr_binding.egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX; + oxr_binding.egl.getProcAddress = eglGetProcAddress; + oxr_binding.egl.display = ctx_egl.getDisplay(); + oxr_binding.egl.config = ctx_egl.getConfig(); + oxr_binding.egl.context = ctx_egl.getContext(); + } } -# else - GHOST_ContextGLX &ctx_glx = static_cast<GHOST_ContextGLX &>(ghost_ctx); - XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.m_display, ctx_glx.m_fbconfig); + else { + GHOST_ContextGLX &ctx_glx = static_cast<GHOST_ContextGLX &>(ghost_ctx); + XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.m_display, ctx_glx.m_fbconfig); - oxr_binding.glx.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR; - oxr_binding.glx.xDisplay = ctx_glx.m_display; - oxr_binding.glx.glxFBConfig = ctx_glx.m_fbconfig; - oxr_binding.glx.glxDrawable = ctx_glx.m_window; - oxr_binding.glx.glxContext = ctx_glx.m_context; - oxr_binding.glx.visualid = visual_info->visualid; + oxr_binding.glx.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR; + oxr_binding.glx.xDisplay = ctx_glx.m_display; + oxr_binding.glx.glxFBConfig = ctx_glx.m_fbconfig; + oxr_binding.glx.glxDrawable = ctx_glx.m_window; + oxr_binding.glx.glxContext = ctx_glx.m_context; + oxr_binding.glx.visualid = visual_info->visualid; - XFree(visual_info); + XFree(visual_info); # endif + } #elif defined(WIN32) GHOST_ContextWGL &ctx_wgl = static_cast<GHOST_ContextWGL &>(ghost_ctx); @@ -144,14 +165,6 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { oxr_binding.wgl.hGLRC = ctx_wgl.m_hGLRC; #endif -#if defined(WITH_GHOST_WAYLAND) - GHOST_ContextEGL &ctx_wl_egl = static_cast<GHOST_ContextEGL &>(ghost_ctx); - if (dynamic_cast<const GHOST_SystemWayland *const>(ctx_wl_egl.m_system)) { - oxr_binding.wl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR; - oxr_binding.wl.display = (struct wl_display *)ctx_wl_egl.m_nativeDisplay; - } -#endif - /* Generate a frame-buffer to use for blitting into the texture. */ glGenFramebuffers(1, &m_fbo); } diff --git a/intern/ghost/intern/GHOST_Xr_openxr_includes.h b/intern/ghost/intern/GHOST_Xr_openxr_includes.h index 9706f51c027..1c16f746f7a 100644 --- a/intern/ghost/intern/GHOST_Xr_openxr_includes.h +++ b/intern/ghost/intern/GHOST_Xr_openxr_includes.h @@ -28,13 +28,8 @@ # include <d3d12.h> #endif #ifdef WITH_GHOST_X11 -# ifdef WITH_GL_EGL -/* TODO: Why do we have to create this typedef manually? */ -typedef void (*(*PFNEGLGETPROCADDRESSPROC)(const char *procname))(void); -# include <GL/eglew.h> -# else -# include <GL/glxew.h> -# endif +# include <epoxy/egl.h> +# include <epoxy/glx.h> #endif #include <openxr/openxr.h> diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt index 9cc406313c7..3f74f97f115 100644 --- a/intern/ghost/test/CMakeLists.txt +++ b/intern/ghost/test/CMakeLists.txt @@ -89,8 +89,6 @@ if(UNIX AND NOT APPLE) set(WITH_GHOST_X11 ON) endif() -# for now... default to this -add_definitions(-DWITH_GL_PROFILE_COMPAT) # BLF needs this to ignore GPU library add_definitions(-DBLF_STANDALONE) @@ -155,13 +153,6 @@ suffix_relpaths(SRC_NEW "${SRC}" "../../../extern/wcwidth/") include_directories(${INC_NEW}) add_library(wcwidth_lib ${SRC_NEW}) -# glew-mx -include(${CMAKE_SOURCE_DIR}/../../../intern/glew-mx/CMakeLists.txt) -suffix_relpaths(INC_NEW "${INC}" "../../../intern/glew-mx/") -suffix_relpaths(SRC_NEW "${SRC}" "../../../intern/glew-mx/") -include_directories(${INC_NEW}) -add_library(glewmx_lib ${SRC_NEW}) - # grr, blenfont needs BLI include_directories( "../../../source/blender/blenlib" @@ -217,21 +208,12 @@ endif() if(UNIX AND NOT APPLE) find_package(X11 REQUIRED) - find_package(GLEW) - - if(NOT GLEW_FOUND) - message(FATAL_ERROR "GLEW is required to build blender, install it or disable WITH_SYSTEM_GLEW") - endif() set(PLATFORM_LINKLIBS ${X11_X11_LIB} ${X11_Xinput_LIB} - ${GLEW_LIBRARY} -lpthread ) -else() - # set(GLEW_LIBRARY "") # unused - set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include") endif() string(APPEND CMAKE_C_FLAGS " ${PLATFORM_CFLAGS}") @@ -246,7 +228,6 @@ add_executable(gears_c target_link_libraries(gears_c ghost_lib - glewmx_lib string_lib ${OPENGL_gl_LIBRARY} ${CMAKE_DL_LIBS} @@ -260,7 +241,6 @@ add_executable(gears_cpp target_link_libraries(gears_cpp ghost_lib - glewmx_lib string_lib ${OPENGL_gl_LIBRARY} ${CMAKE_DL_LIBS} @@ -287,7 +267,6 @@ target_link_libraries(multitest_c # imbuf_lib ghost_lib bli_lib # again... - glewmx_lib string_lib numaapi_lib guardedalloc_lib diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp index 5a43543d163..f5ef2527d75 100644 --- a/intern/ghost/test/gears/GHOST_Test.cpp +++ b/intern/ghost/test/gears/GHOST_Test.cpp @@ -559,10 +559,12 @@ bool Application::processEvent(GHOST_IEvent *event) break; case GHOST_kKeyS: // toggle mono and stereo - if (stereo) + if (stereo) { stereo = false; - else + } + else { stereo = true; + } break; case GHOST_kKeyT: @@ -680,8 +682,9 @@ int main(int /*argc*/, char ** /*argv*/) if (lresult == ERROR_SUCCESS) printf("Successfully set value for key\n"); regkey.Close(); - if (lresult == ERROR_SUCCESS) + if (lresult == ERROR_SUCCESS) { printf("Successfully closed key\n"); + } // regkey.Write("2"); } #endif // WIN32 diff --git a/intern/ghost/test/multitest/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c index 157e4f1b0f2..99b88dfb525 100644 --- a/intern/ghost/test/multitest/MultiTest.c +++ b/intern/ghost/test/multitest/MultiTest.c @@ -179,37 +179,44 @@ static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press) { switch (key) { case GHOST_kKeyC: - if (press) + if (press) { GHOST_SetCursorShape(mw->win, (GHOST_TStandardCursor)(rand() % (GHOST_kStandardCursorNumCursors))); + } break; case GHOST_kKeyLeftBracket: - if (press) + if (press) { GHOST_SetCursorVisibility(mw->win, 0); + } break; case GHOST_kKeyRightBracket: - if (press) + if (press) { GHOST_SetCursorVisibility(mw->win, 1); + } break; case GHOST_kKeyE: - if (press) + if (press) { multitestapp_toggle_extra_window(mw->app); + } break; case GHOST_kKeyQ: - if (press) + if (press) { multitestapp_exit(mw->app); + } break; case GHOST_kKeyT: - if (press) + if (press) { mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/"); + } break; case GHOST_kKeyR: if (press) { int i; mainwindow_log(mw, "Invalidating window 10 times"); - for (i = 0; i < 10; i++) + for (i = 0; i < 10; i++) { GHOST_InvalidateWindow(mw->win); + } } break; case GHOST_kKeyF11: @@ -328,9 +335,7 @@ MainWindow *mainwindow_new(MultiTestApp *app) return mw; } - else { - return NULL; - } + return NULL; } void mainwindow_free(MainWindow *mw) diff --git a/intern/glew-mx/CMakeLists.txt b/intern/glew-mx/CMakeLists.txt deleted file mode 100644 index 49e9762672f..00000000000 --- a/intern/glew-mx/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# Copyright 2014 Blender Foundation. All rights reserved. - -set(INC - . -) - -set(INC_SYS - ${GLEW_INCLUDE_PATH} -) - -set(SRC - intern/glew-mx.c - - glew-mx.h - intern/gl-deprecated.h - intern/symbol-binding.h -) - -set(LIB -) - -add_definitions(${GL_DEFINITIONS}) - -blender_add_lib(bf_intern_glew_mx "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/intern/glew-mx/glew-mx.h b/intern/glew-mx/glew-mx.h deleted file mode 100644 index e7972697010..00000000000 --- a/intern/glew-mx/glew-mx.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2014 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup intern_glew-mx - * - * Support for GLEW Multiple rendering conteXts (MX) - * Maintained as a Blender Library. - * - * Different rendering contexts may have different entry points - * to extension functions of the same name. So it can cause - * problems if, for example, a second context uses a pointer to - * say, glActiveTextureARB, that was queried from the first context. - * - * GLEW has basic support for multiple contexts by enabling WITH_GLEW_MX, - * but it does not provide a full implementation. This is because - * there are too many questions about thread safety and memory - * allocation that are up to the user of GLEW. - * - * This implementation is very basic and isn't thread safe. - * For a single context the overhead should be - * no more than using GLEW without WITH_GLEW_MX enabled. - */ - -#ifndef __GLEW_MX_H__ -#define __GLEW_MX_H__ - -#include <GL/glew.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#include "intern/symbol-binding.h" - -/* If compiling only for OpenGL 3.2 Core Profile then we should make sure - * no legacy API entries or symbolic constants are used. - */ -#if (!defined(WITH_LEGACY_OPENGL)) || defined(WITH_GL_PROFILE_CORE) && \ - !defined(WITH_GL_PROFILE_COMPAT) && \ - !defined(WITH_GL_PROFILE_ES20) -# include "intern/gl-deprecated.h" -#endif - -GLenum glew_chk(GLenum error, const char *file, int line, const char *text); - -#ifndef NDEBUG -# define GLEW_CHK(x) glew_chk((x), __FILE__, __LINE__, # x) -#else -# define GLEW_CHK(x) glew_chk((x), NULL, 0, NULL) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __GLEW_MX_H__ */ diff --git a/intern/glew-mx/intern/gl-deprecated.h b/intern/glew-mx/intern/gl-deprecated.h deleted file mode 100644 index 762699d74d2..00000000000 --- a/intern/glew-mx/intern/gl-deprecated.h +++ /dev/null @@ -1,848 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2014 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup intern_glew-mx - * Utility used to check for use of deprecated functions. - */ - -#ifndef __GL_DEPRECATED_H__ -#define __GL_DEPRECATED_H__ - -// GL Version 1.0 -#undef glAccum -#define glAccum DO_NOT_USE_glAccum -#undef glAlphaFunc -#define glAlphaFunc DO_NOT_USE_glAlphaFunc -#undef glBegin -#define glBegin DO_NOT_USE_glBegin -#undef glBitmap -#define glBitmap DO_NOT_USE_glBitmap -#undef glCallList -#define glCallList DO_NOT_USE_glCallList -#undef glCallLists -#define glCallLists DO_NOT_USE_glCallLists -#undef glClearAccum -#define glClearAccum DO_NOT_USE_glClearAccum -#undef glClearIndex -#define glClearIndex DO_NOT_USE_glClearIndex -#undef glClipPlane -#define glClipPlane DO_NOT_USE_glClipPlane -#undef glColor3b -#define glColor3b DO_NOT_USE_glColor3b -#undef glColor3bv -#define glColor3bv DO_NOT_USE_glColor3bv -#undef glColor3d -#define glColor3d DO_NOT_USE_glColor3d -#undef glColor3dv -#define glColor3dv DO_NOT_USE_glColor3dv -#undef glColor3f -#define glColor3f DO_NOT_USE_glColor3f -#undef glColor3fv -#define glColor3fv DO_NOT_USE_glColor3fv -#undef glColor3i -#define glColor3i DO_NOT_USE_glColor3i -#undef glColor3iv -#define glColor3iv DO_NOT_USE_glColor3iv -#undef glColor3s -#define glColor3s DO_NOT_USE_glColor3s -#undef glColor3sv -#define glColor3sv DO_NOT_USE_glColor3sv -#undef glColor3ub -#define glColor3ub DO_NOT_USE_glColor3ub -#undef glColor3ubv -#define glColor3ubv DO_NOT_USE_glColor3ubv -#undef glColor3ui -#define glColor3ui DO_NOT_USE_glColor3ui -#undef glColor3uiv -#define glColor3uiv DO_NOT_USE_glColor3uiv -#undef glColor3us -#define glColor3us DO_NOT_USE_glColor3us -#undef glColor3usv -#define glColor3usv DO_NOT_USE_glColor3usv -#undef glColor4b -#define glColor4b DO_NOT_USE_glColor4b -#undef glColor4bv -#define glColor4bv DO_NOT_USE_glColor4bv -#undef glColor4d -#define glColor4d DO_NOT_USE_glColor4d -#undef glColor4dv -#define glColor4dv DO_NOT_USE_glColor4dv -#undef glColor4f -#define glColor4f DO_NOT_USE_glColor4f -#undef glColor4fv -#define glColor4fv DO_NOT_USE_glColor4fv -#undef glColor4i -#define glColor4i DO_NOT_USE_glColor4i -#undef glColor4iv -#define glColor4iv DO_NOT_USE_glColor4iv -#undef glColor4s -#define glColor4s DO_NOT_USE_glColor4s -#undef glColor4sv -#define glColor4sv DO_NOT_USE_glColor4sv -#undef glColor4ub -#define glColor4ub DO_NOT_USE_glColor4ub -#undef glColor4ubv -#define glColor4ubv DO_NOT_USE_glColor4ubv -#undef glColor4ui -#define glColor4ui DO_NOT_USE_glColor4ui -#undef glColor4uiv -#define glColor4uiv DO_NOT_USE_glColor4uiv -#undef glColor4us -#define glColor4us DO_NOT_USE_glColor4us -#undef glColor4usv -#define glColor4usv DO_NOT_USE_glColor4usv -#undef glColorMaterial -#define glColorMaterial DO_NOT_USE_glColorMaterial -#undef glCopyPixels -#define glCopyPixels DO_NOT_USE_glCopyPixels -#undef glDeleteLists -#define glDeleteLists DO_NOT_USE_glDeleteLists -#undef glDrawPixels -#define glDrawPixels DO_NOT_USE_glDrawPixels -#undef glEdgeFlag -#define glEdgeFlag DO_NOT_USE_glEdgeFlag -#undef glEdgeFlagv -#define glEdgeFlagv DO_NOT_USE_glEdgeFlagv -#undef glEnd -#define glEnd DO_NOT_USE_glEnd -#undef glEndList -#define glEndList DO_NOT_USE_glEndList -#undef glEvalCoord1d -#define glEvalCoord1d DO_NOT_USE_glEvalCoord1d -#undef glEvalCoord1dv -#define glEvalCoord1dv DO_NOT_USE_glEvalCoord1dv -#undef glEvalCoord1f -#define glEvalCoord1f DO_NOT_USE_glEvalCoord1f -#undef glEvalCoord1fv -#define glEvalCoord1fv DO_NOT_USE_glEvalCoord1fv -#undef glEvalCoord2d -#define glEvalCoord2d DO_NOT_USE_glEvalCoord2d -#undef glEvalCoord2dv -#define glEvalCoord2dv DO_NOT_USE_glEvalCoord2dv -#undef glEvalCoord2f -#define glEvalCoord2f DO_NOT_USE_glEvalCoord2f -#undef glEvalCoord2fv -#define glEvalCoord2fv DO_NOT_USE_glEvalCoord2fv -#undef glEvalMesh1 -#define glEvalMesh1 DO_NOT_USE_glEvalMesh1 -#undef glEvalMesh2 -#define glEvalMesh2 DO_NOT_USE_glEvalMesh2 -#undef glEvalPoint1 -#define glEvalPoint1 DO_NOT_USE_glEvalPoint1 -#undef glEvalPoint2 -#define glEvalPoint2 DO_NOT_USE_glEvalPoint2 -#undef glFeedbackBuffer -#define glFeedbackBuffer DO_NOT_USE_glFeedbackBuffer -#undef glFogf -#define glFogf DO_NOT_USE_glFogf -#undef glFogfv -#define glFogfv DO_NOT_USE_glFogfv -#undef glFogi -#define glFogi DO_NOT_USE_glFogi -#undef glFogiv -#define glFogiv DO_NOT_USE_glFogiv -#undef glFrustum -#define glFrustum DO_NOT_USE_glFrustum -#undef glGenLists -#define glGenLists DO_NOT_USE_glGenLists -#undef glGetClipPlane -#define glGetClipPlane DO_NOT_USE_glGetClipPlane -#undef glGetLightfv -#define glGetLightfv DO_NOT_USE_glGetLightfv -#undef glGetLightiv -#define glGetLightiv DO_NOT_USE_glGetLightiv -#undef glGetMapdv -#define glGetMapdv DO_NOT_USE_glGetMapdv -#undef glGetMapfv -#define glGetMapfv DO_NOT_USE_glGetMapfv -#undef glGetMapiv -#define glGetMapiv DO_NOT_USE_glGetMapiv -#undef glGetMaterialfv -#define glGetMaterialfv DO_NOT_USE_glGetMaterialfv -#undef glGetMaterialiv -#define glGetMaterialiv DO_NOT_USE_glGetMaterialiv -#undef glGetPixelMapfv -#define glGetPixelMapfv DO_NOT_USE_glGetPixelMapfv -#undef glGetPixelMapuiv -#define glGetPixelMapuiv DO_NOT_USE_glGetPixelMapuiv -#undef glGetPixelMapusv -#define glGetPixelMapusv DO_NOT_USE_glGetPixelMapusv -#undef glGetPolygonStipple -#define glGetPolygonStipple DO_NOT_USE_glGetPolygonStipple -#undef glGetTexEnvfv -#define glGetTexEnvfv DO_NOT_USE_glGetTexEnvfv -#undef glGetTexEnviv -#define glGetTexEnviv DO_NOT_USE_glGetTexEnviv -#undef glGetTexGendv -#define glGetTexGendv DO_NOT_USE_glGetTexGendv -#undef glGetTexGenfv -#define glGetTexGenfv DO_NOT_USE_glGetTexGenfv -#undef glGetTexGeniv -#define glGetTexGeniv DO_NOT_USE_glGetTexGeniv -#undef glIndexMask -#define glIndexMask DO_NOT_USE_glIndexMask -#undef glIndexd -#define glIndexd DO_NOT_USE_glIndexd -#undef glIndexdv -#define glIndexdv DO_NOT_USE_glIndexdv -#undef glIndexf -#define glIndexf DO_NOT_USE_glIndexf -#undef glIndexfv -#define glIndexfv DO_NOT_USE_glIndexfv -#undef glIndexi -#define glIndexi DO_NOT_USE_glIndexi -#undef glIndexiv -#define glIndexiv DO_NOT_USE_glIndexiv -#undef glIndexs -#define glIndexs DO_NOT_USE_glIndexs -#undef glIndexsv -#define glIndexsv DO_NOT_USE_glIndexsv -#undef glInitNames -#define glInitNames DO_NOT_USE_glInitNames -#undef glIsList -#define glIsList DO_NOT_USE_glIsList -#undef glLightModelf -#define glLightModelf DO_NOT_USE_glLightModelf -#undef glLightModelfv -#define glLightModelfv DO_NOT_USE_glLightModelfv -#undef glLightModeli -#define glLightModeli DO_NOT_USE_glLightModeli -#undef glLightModeliv -#define glLightModeliv DO_NOT_USE_glLightModeliv -#undef glLightf -#define glLightf DO_NOT_USE_glLightf -#undef glLightfv -#define glLightfv DO_NOT_USE_glLightfv -#undef glLighti -#define glLighti DO_NOT_USE_glLighti -#undef glLightiv -#define glLightiv DO_NOT_USE_glLightiv -#undef glLineStipple -#define glLineStipple DO_NOT_USE_glLineStipple -#undef glListBase -#define glListBase DO_NOT_USE_glListBase -#undef glLoadIdentity -#define glLoadIdentity DO_NOT_USE_glLoadIdentity -#undef glLoadMatrixd -#define glLoadMatrixd DO_NOT_USE_glLoadMatrixd -#undef glLoadMatrixf -#define glLoadMatrixf DO_NOT_USE_glLoadMatrixf -#undef glLoadName -#define glLoadName DO_NOT_USE_glLoadName -#undef glMap1d -#define glMap1d DO_NOT_USE_glMap1d -#undef glMap1f -#define glMap1f DO_NOT_USE_glMap1f -#undef glMap2d -#define glMap2d DO_NOT_USE_glMap2d -#undef glMap2f -#define glMap2f DO_NOT_USE_glMap2f -#undef glMapGrid1d -#define glMapGrid1d DO_NOT_USE_glMapGrid1d -#undef glMapGrid1f -#define glMapGrid1f DO_NOT_USE_glMapGrid1f -#undef glMapGrid2d -#define glMapGrid2d DO_NOT_USE_glMapGrid2d -#undef glMapGrid2f -#define glMapGrid2f DO_NOT_USE_glMapGrid2f -#undef glMaterialf -#define glMaterialf DO_NOT_USE_glMaterialf -#undef glMaterialfv -#define glMaterialfv DO_NOT_USE_glMaterialfv -#undef glMateriali -#define glMateriali DO_NOT_USE_glMateriali -#undef glMaterialiv -#define glMaterialiv DO_NOT_USE_glMaterialiv -#undef glMatrixMode -#define glMatrixMode DO_NOT_USE_glMatrixMode -#undef glMultMatrixd -#define glMultMatrixd DO_NOT_USE_glMultMatrixd -#undef glMultMatrixf -#define glMultMatrixf DO_NOT_USE_glMultMatrixf -#undef glNewList -#define glNewList DO_NOT_USE_glNewList -#undef glNormal3b -#define glNormal3b DO_NOT_USE_glNormal3b -#undef glNormal3bv -#define glNormal3bv DO_NOT_USE_glNormal3bv -#undef glNormal3d -#define glNormal3d DO_NOT_USE_glNormal3d -#undef glNormal3dv -#define glNormal3dv DO_NOT_USE_glNormal3dv -#undef glNormal3f -#define glNormal3f DO_NOT_USE_glNormal3f -#undef glNormal3fv -#define glNormal3fv DO_NOT_USE_glNormal3fv -#undef glNormal3i -#define glNormal3i DO_NOT_USE_glNormal3i -#undef glNormal3iv -#define glNormal3iv DO_NOT_USE_glNormal3iv -#undef glNormal3s -#define glNormal3s DO_NOT_USE_glNormal3s -#undef glNormal3sv -#define glNormal3sv DO_NOT_USE_glNormal3sv -#undef glOrtho -#define glOrtho DO_NOT_USE_glOrtho -#undef glPassThrough -#define glPassThrough DO_NOT_USE_glPassThrough -#undef glPixelMapfv -#define glPixelMapfv DO_NOT_USE_glPixelMapfv -#undef glPixelMapuiv -#define glPixelMapuiv DO_NOT_USE_glPixelMapuiv -#undef glPixelMapusv -#define glPixelMapusv DO_NOT_USE_glPixelMapusv -#undef glPixelTransferf -#define glPixelTransferf DO_NOT_USE_glPixelTransferf -#undef glPixelTransferi -#define glPixelTransferi DO_NOT_USE_glPixelTransferi -#undef glPixelZoom -#define glPixelZoom DO_NOT_USE_glPixelZoom -#undef glPolygonStipple -#define glPolygonStipple DO_NOT_USE_glPolygonStipple -#undef glPopAttrib -#define glPopAttrib DO_NOT_USE_glPopAttrib -#undef glPopMatrix -#define glPopMatrix DO_NOT_USE_glPopMatrix -#undef glPopName -#define glPopName DO_NOT_USE_glPopName -#undef glPushAttrib -#define glPushAttrib DO_NOT_USE_glPushAttrib -#undef glPushMatrix -#define glPushMatrix DO_NOT_USE_glPushMatrix -#undef glPushName -#define glPushName DO_NOT_USE_glPushName -#undef glRasterPos2d -#define glRasterPos2d DO_NOT_USE_glRasterPos2d -#undef glRasterPos2dv -#define glRasterPos2dv DO_NOT_USE_glRasterPos2dv -#undef glRasterPos2f -#define glRasterPos2f DO_NOT_USE_glRasterPos2f -#undef glRasterPos2fv -#define glRasterPos2fv DO_NOT_USE_glRasterPos2fv -#undef glRasterPos2i -#define glRasterPos2i DO_NOT_USE_glRasterPos2i -#undef glRasterPos2iv -#define glRasterPos2iv DO_NOT_USE_glRasterPos2iv -#undef glRasterPos2s -#define glRasterPos2s DO_NOT_USE_glRasterPos2s -#undef glRasterPos2sv -#define glRasterPos2sv DO_NOT_USE_glRasterPos2sv -#undef glRasterPos3d -#define glRasterPos3d DO_NOT_USE_glRasterPos3d -#undef glRasterPos3dv -#define glRasterPos3dv DO_NOT_USE_glRasterPos3dv -#undef glRasterPos3f -#define glRasterPos3f DO_NOT_USE_glRasterPos3f -#undef glRasterPos3fv -#define glRasterPos3fv DO_NOT_USE_glRasterPos3fv -#undef glRasterPos3i -#define glRasterPos3i DO_NOT_USE_glRasterPos3i -#undef glRasterPos3iv -#define glRasterPos3iv DO_NOT_USE_glRasterPos3iv -#undef glRasterPos3s -#define glRasterPos3s DO_NOT_USE_glRasterPos3s -#undef glRasterPos3sv -#define glRasterPos3sv DO_NOT_USE_glRasterPos3sv -#undef glRasterPos4d -#define glRasterPos4d DO_NOT_USE_glRasterPos4d -#undef glRasterPos4dv -#define glRasterPos4dv DO_NOT_USE_glRasterPos4dv -#undef glRasterPos4f -#define glRasterPos4f DO_NOT_USE_glRasterPos4f -#undef glRasterPos4fv -#define glRasterPos4fv DO_NOT_USE_glRasterPos4fv -#undef glRasterPos4i -#define glRasterPos4i DO_NOT_USE_glRasterPos4i -#undef glRasterPos4iv -#define glRasterPos4iv DO_NOT_USE_glRasterPos4iv -#undef glRasterPos4s -#define glRasterPos4s DO_NOT_USE_glRasterPos4s -#undef glRasterPos4sv -#define glRasterPos4sv DO_NOT_USE_glRasterPos4sv -#undef glRectd -#define glRectd DO_NOT_USE_glRectd -#undef glRectdv -#define glRectdv DO_NOT_USE_glRectdv -#undef glRectf -#define glRectf DO_NOT_USE_glRectf -#undef glRectfv -#define glRectfv DO_NOT_USE_glRectfv -#undef glRecti -#define glRecti DO_NOT_USE_glRecti -#undef glRectiv -#define glRectiv DO_NOT_USE_glRectiv -#undef glRects -#define glRects DO_NOT_USE_glRects -#undef glRectsv -#define glRectsv DO_NOT_USE_glRectsv -#undef glRenderMode -#define glRenderMode DO_NOT_USE_glRenderMode -#undef glRotated -#define glRotated DO_NOT_USE_glRotated -#undef glRotatef -#define glRotatef DO_NOT_USE_glRotatef -#undef glScaled -#define glScaled DO_NOT_USE_glScaled -#undef glScalef -#define glScalef DO_NOT_USE_glScalef -#undef glSelectBuffer -#define glSelectBuffer DO_NOT_USE_glSelectBuffer -#undef glShadeModel -#define glShadeModel DO_NOT_USE_glShadeModel -#undef glTexCoord1d -#define glTexCoord1d DO_NOT_USE_glTexCoord1d -#undef glTexCoord1dv -#define glTexCoord1dv DO_NOT_USE_glTexCoord1dv -#undef glTexCoord1f -#define glTexCoord1f DO_NOT_USE_glTexCoord1f -#undef glTexCoord1fv -#define glTexCoord1fv DO_NOT_USE_glTexCoord1fv -#undef glTexCoord1i -#define glTexCoord1i DO_NOT_USE_glTexCoord1i -#undef glTexCoord1iv -#define glTexCoord1iv DO_NOT_USE_glTexCoord1iv -#undef glTexCoord1s -#define glTexCoord1s DO_NOT_USE_glTexCoord1s -#undef glTexCoord1sv -#define glTexCoord1sv DO_NOT_USE_glTexCoord1sv -#undef glTexCoord2d -#define glTexCoord2d DO_NOT_USE_glTexCoord2d -#undef glTexCoord2dv -#define glTexCoord2dv DO_NOT_USE_glTexCoord2dv -#undef glTexCoord2f -#define glTexCoord2f DO_NOT_USE_glTexCoord2f -#undef glTexCoord2fv -#define glTexCoord2fv DO_NOT_USE_glTexCoord2fv -#undef glTexCoord2i -#define glTexCoord2i DO_NOT_USE_glTexCoord2i -#undef glTexCoord2iv -#define glTexCoord2iv DO_NOT_USE_glTexCoord2iv -#undef glTexCoord2s -#define glTexCoord2s DO_NOT_USE_glTexCoord2s -#undef glTexCoord2sv -#define glTexCoord2sv DO_NOT_USE_glTexCoord2sv -#undef glTexCoord3d -#define glTexCoord3d DO_NOT_USE_glTexCoord3d -#undef glTexCoord3dv -#define glTexCoord3dv DO_NOT_USE_glTexCoord3dv -#undef glTexCoord3f -#define glTexCoord3f DO_NOT_USE_glTexCoord3f -#undef glTexCoord3fv -#define glTexCoord3fv DO_NOT_USE_glTexCoord3fv -#undef glTexCoord3i -#define glTexCoord3i DO_NOT_USE_glTexCoord3i -#undef glTexCoord3iv -#define glTexCoord3iv DO_NOT_USE_glTexCoord3iv -#undef glTexCoord3s -#define glTexCoord3s DO_NOT_USE_glTexCoord3s -#undef glTexCoord3sv -#define glTexCoord3sv DO_NOT_USE_glTexCoord3sv -#undef glTexCoord4d -#define glTexCoord4d DO_NOT_USE_glTexCoord4d -#undef glTexCoord4dv -#define glTexCoord4dv DO_NOT_USE_glTexCoord4dv -#undef glTexCoord4f -#define glTexCoord4f DO_NOT_USE_glTexCoord4f -#undef glTexCoord4fv -#define glTexCoord4fv DO_NOT_USE_glTexCoord4fv -#undef glTexCoord4i -#define glTexCoord4i DO_NOT_USE_glTexCoord4i -#undef glTexCoord4iv -#define glTexCoord4iv DO_NOT_USE_glTexCoord4iv -#undef glTexCoord4s -#define glTexCoord4s DO_NOT_USE_glTexCoord4s -#undef glTexCoord4sv -#define glTexCoord4sv DO_NOT_USE_glTexCoord4sv -#undef glTexEnvf -#define glTexEnvf DO_NOT_USE_glTexEnvf -#undef glTexEnvfv -#define glTexEnvfv DO_NOT_USE_glTexEnvfv -#undef glTexEnvi -#define glTexEnvi DO_NOT_USE_glTexEnvi -#undef glTexEnviv -#define glTexEnviv DO_NOT_USE_glTexEnviv -#undef glTexGend -#define glTexGend DO_NOT_USE_glTexGend -#undef glTexGendv -#define glTexGendv DO_NOT_USE_glTexGendv -#undef glTexGenf -#define glTexGenf DO_NOT_USE_glTexGenf -#undef glTexGenfv -#define glTexGenfv DO_NOT_USE_glTexGenfv -#undef glTexGeni -#define glTexGeni DO_NOT_USE_glTexGeni -#undef glTexGeniv -#define glTexGeniv DO_NOT_USE_glTexGeniv -#undef glTranslated -#define glTranslated DO_NOT_USE_glTranslated -#undef glTranslatef -#define glTranslatef DO_NOT_USE_glTranslatef -#undef glVertex2d -#define glVertex2d DO_NOT_USE_glVertex2d -#undef glVertex2dv -#define glVertex2dv DO_NOT_USE_glVertex2dv -#undef glVertex2f -#define glVertex2f DO_NOT_USE_glVertex2f -#undef glVertex2fv -#define glVertex2fv DO_NOT_USE_glVertex2fv -#undef glVertex2i -#define glVertex2i DO_NOT_USE_glVertex2i -#undef glVertex2iv -#define glVertex2iv DO_NOT_USE_glVertex2iv -#undef glVertex2s -#define glVertex2s DO_NOT_USE_glVertex2s -#undef glVertex2sv -#define glVertex2sv DO_NOT_USE_glVertex2sv -#undef glVertex3d -#define glVertex3d DO_NOT_USE_glVertex3d -#undef glVertex3dv -#define glVertex3dv DO_NOT_USE_glVertex3dv -#undef glVertex3f -#define glVertex3f DO_NOT_USE_glVertex3f -#undef glVertex3fv -#define glVertex3fv DO_NOT_USE_glVertex3fv -#undef glVertex3i -#define glVertex3i DO_NOT_USE_glVertex3i -#undef glVertex3iv -#define glVertex3iv DO_NOT_USE_glVertex3iv -#undef glVertex3s -#define glVertex3s DO_NOT_USE_glVertex3s -#undef glVertex3sv -#define glVertex3sv DO_NOT_USE_glVertex3sv -#undef glVertex4d -#define glVertex4d DO_NOT_USE_glVertex4d -#undef glVertex4dv -#define glVertex4dv DO_NOT_USE_glVertex4dv -#undef glVertex4f -#define glVertex4f DO_NOT_USE_glVertex4f -#undef glVertex4fv -#define glVertex4fv DO_NOT_USE_glVertex4fv -#undef glVertex4i -#define glVertex4i DO_NOT_USE_glVertex4i -#undef glVertex4iv -#define glVertex4iv DO_NOT_USE_glVertex4iv -#undef glVertex4s -#define glVertex4s DO_NOT_USE_glVertex4s -#undef glVertex4sv -#define glVertex4sv DO_NOT_USE_glVertex4sv - -// GL Version 1.1 -#undef glAreTexturesResident -#define glAreTexturesResident DO_NOT_USE_glAreTexturesResident -#undef glArrayElement -#define glArrayElement DO_NOT_USE_glArrayElement -#undef glColorPointer -#define glColorPointer DO_NOT_USE_glColorPointer -#undef glDisableClientState -#define glDisableClientState DO_NOT_USE_glDisableClientState -#undef glEdgeFlagPointer -#define glEdgeFlagPointer DO_NOT_USE_glEdgeFlagPointer -#undef glEnableClientState -#define glEnableClientState DO_NOT_USE_glEnableClientState -#undef glIndexPointer -#define glIndexPointer DO_NOT_USE_glIndexPointer -#undef glIndexub -#define glIndexub DO_NOT_USE_glIndexub -#undef glIndexubv -#define glIndexubv DO_NOT_USE_glIndexubv -#undef glInterleavedArrays -#define glInterleavedArrays DO_NOT_USE_glInterleavedArrays -#undef glNormalPointer -#define glNormalPointer DO_NOT_USE_glNormalPointer -#undef glPopClientAttrib -#define glPopClientAttrib DO_NOT_USE_glPopClientAttrib -#undef glPrioritizeTextures -#define glPrioritizeTextures DO_NOT_USE_glPrioritizeTextures -#undef glPushClientAttrib -#define glPushClientAttrib DO_NOT_USE_glPushClientAttrib -#undef glTexCoordPointer -#define glTexCoordPointer DO_NOT_USE_glTexCoordPointer -#undef glVertexPointer -#define glVertexPointer DO_NOT_USE_glVertexPointer - -// GL Version1.2 -#undef glColorSubTable -#define glColorSubTable DO_NOT_USE_glColorSubTable -#undef glColorTable -#define glColorTable DO_NOT_USE_glColorTable -#undef glColorTableParameterfv -#define glColorTableParameterfv DO_NOT_USE_glColorTableParameterfv -#undef glColorTableParameteriv -#define glColorTableParameteriv DO_NOT_USE_glColorTableParameteriv -#undef glConvolutionFilter1D -#define glConvolutionFilter1D DO_NOT_USE_glConvolutionFilter1D -#undef glConvolutionFilter2D -#define glConvolutionFilter2D DO_NOT_USE_glConvolutionFilter2D -#undef glConvolutionParameterf -#define glConvolutionParameterf DO_NOT_USE_glConvolutionParameterf -#undef glConvolutionParameterfv -#define glConvolutionParameterfv DO_NOT_USE_glConvolutionParameterfv -#undef glConvolutionParameteri -#define glConvolutionParameteri DO_NOT_USE_glConvolutionParameteri -#undef glConvolutionParameteriv -#define glConvolutionParameteriv DO_NOT_USE_glConvolutionParameteriv -#undef glCopyColorSubTable -#define glCopyColorSubTable DO_NOT_USE_glCopyColorSubTable -#undef glCopyColorTable -#define glCopyColorTable DO_NOT_USE_glCopyColorTable -#undef glCopyConvolutionFilter1D -#define glCopyConvolutionFilter1D DO_NOT_USE_glCopyConvolutionFilter1D -#undef glCopyConvolutionFilter2D -#define glCopyConvolutionFilter2D DO_NOT_USE_glCopyConvolutionFilter2D -#undef glGetColorTable -#define glGetColorTable DO_NOT_USE_glGetColorTable -#undef glGetColorTableParameterfv -#define glGetColorTableParameterfv DO_NOT_USE_glGetColorTableParameterfv -#undef glGetColorTableParameteriv -#define glGetColorTableParameteriv DO_NOT_USE_glGetColorTableParameteriv -#undef glGetConvolutionFilter -#define glGetConvolutionFilter DO_NOT_USE_glGetConvolutionFilter -#undef glGetConvolutionParameterfv -#define glGetConvolutionParameterfv DO_NOT_USE_glGetConvolutionParameterfv -#undef glGetConvolutionParameteriv -#define glGetConvolutionParameteriv DO_NOT_USE_glGetConvolutionParameteriv -#undef glGetHistogram -#define glGetHistogram DO_NOT_USE_glGetHistogram -#undef glGetHistogramParameterfv -#define glGetHistogramParameterfv DO_NOT_USE_glGetHistogramParameterfv -#undef glGetHistogramParameteriv -#define glGetHistogramParameteriv DO_NOT_USE_glGetHistogramParameteriv -#undef glGetMinmax -#define glGetMinmax DO_NOT_USE_glGetMinmax -#undef glGetMinmaxParameterfv -#define glGetMinmaxParameterfv DO_NOT_USE_glGetMinmaxParameterfv -#undef glGetMinmaxParameteriv -#define glGetMinmaxParameteriv DO_NOT_USE_glGetMinmaxParameteriv -#undef glGetSeparableFilter -#define glGetSeparableFilter DO_NOT_USE_glGetSeparableFilter -#undef glHistogram -#define glHistogram DO_NOT_USE_glHistogram -#undef glMinmax -#define glMinmax DO_NOT_USE_glMinmax -#undef glResetHistogram -#define glResetHistogram DO_NOT_USE_glResetHistogram -#undef glResetMinmax -#define glResetMinmax DO_NOT_USE_glResetMinmax -#undef glSeparableFilter2D -#define glSeparableFilter2D DO_NOT_USE_glSeparableFilter2D - -// GL Version1.3 -#undef glClientActiveTexture -#define glClientActiveTexture DO_NOT_USE_glClientActiveTexture -#undef glLoadTransposeMatrixd -#define glLoadTransposeMatrixd DO_NOT_USE_glLoadTransposeMatrixd -#undef glLoadTransposeMatrixf -#define glLoadTransposeMatrixf DO_NOT_USE_glLoadTransposeMatrixf -#undef glMultTransposeMatrixd -#define glMultTransposeMatrixd DO_NOT_USE_glMultTransposeMatrixd -#undef glMultTransposeMatrixf -#define glMultTransposeMatrixf DO_NOT_USE_glMultTransposeMatrixf -#undef glMultiTexCoord1d -#define glMultiTexCoord1d DO_NOT_USE_glMultiTexCoord1d -#undef glMultiTexCoord1dv -#define glMultiTexCoord1dv DO_NOT_USE_glMultiTexCoord1dv -#undef glMultiTexCoord1f -#define glMultiTexCoord1f DO_NOT_USE_glMultiTexCoord1f -#undef glMultiTexCoord1fv -#define glMultiTexCoord1fv DO_NOT_USE_glMultiTexCoord1fv -#undef glMultiTexCoord1i -#define glMultiTexCoord1i DO_NOT_USE_glMultiTexCoord1i -#undef glMultiTexCoord1iv -#define glMultiTexCoord1iv DO_NOT_USE_glMultiTexCoord1iv -#undef glMultiTexCoord1s -#define glMultiTexCoord1s DO_NOT_USE_glMultiTexCoord1s -#undef glMultiTexCoord1sv -#define glMultiTexCoord1sv DO_NOT_USE_glMultiTexCoord1sv -#undef glMultiTexCoord2d -#define glMultiTexCoord2d DO_NOT_USE_glMultiTexCoord2d -#undef glMultiTexCoord2dv -#define glMultiTexCoord2dv DO_NOT_USE_glMultiTexCoord2dv -#undef glMultiTexCoord2f -#define glMultiTexCoord2f DO_NOT_USE_glMultiTexCoord2f -#undef glMultiTexCoord2fv -#define glMultiTexCoord2fv DO_NOT_USE_glMultiTexCoord2fv -#undef glMultiTexCoord2i -#define glMultiTexCoord2i DO_NOT_USE_glMultiTexCoord2i -#undef glMultiTexCoord2iv -#define glMultiTexCoord2iv DO_NOT_USE_glMultiTexCoord2iv -#undef glMultiTexCoord2s -#define glMultiTexCoord2s DO_NOT_USE_glMultiTexCoord2s -#undef glMultiTexCoord2sv -#define glMultiTexCoord2sv DO_NOT_USE_glMultiTexCoord2sv -#undef glMultiTexCoord3d -#define glMultiTexCoord3d DO_NOT_USE_glMultiTexCoord3d -#undef glMultiTexCoord3dv -#define glMultiTexCoord3dv DO_NOT_USE_glMultiTexCoord3dv -#undef glMultiTexCoord3f -#define glMultiTexCoord3f DO_NOT_USE_glMultiTexCoord3f -#undef glMultiTexCoord3fv -#define glMultiTexCoord3fv DO_NOT_USE_glMultiTexCoord3fv -#undef glMultiTexCoord3i -#define glMultiTexCoord3i DO_NOT_USE_glMultiTexCoord3i -#undef glMultiTexCoord3iv -#define glMultiTexCoord3iv DO_NOT_USE_glMultiTexCoord3iv -#undef glMultiTexCoord3s -#define glMultiTexCoord3s DO_NOT_USE_glMultiTexCoord3s -#undef glMultiTexCoord3sv -#define glMultiTexCoord3sv DO_NOT_USE_glMultiTexCoord3sv -#undef glMultiTexCoord4d -#define glMultiTexCoord4d DO_NOT_USE_glMultiTexCoord4d -#undef glMultiTexCoord4dv -#define glMultiTexCoord4dv DO_NOT_USE_glMultiTexCoord4dv -#undef glMultiTexCoord4f -#define glMultiTexCoord4f DO_NOT_USE_glMultiTexCoord4f -#undef glMultiTexCoord4fv -#define glMultiTexCoord4fv DO_NOT_USE_glMultiTexCoord4fv -#undef glMultiTexCoord4i -#define glMultiTexCoord4i DO_NOT_USE_glMultiTexCoord4i -#undef glMultiTexCoord4iv -#define glMultiTexCoord4iv DO_NOT_USE_glMultiTexCoord4iv -#undef glMultiTexCoord4s -#define glMultiTexCoord4s DO_NOT_USE_glMultiTexCoord4s -#undef glMultiTexCoord4sv -#define glMultiTexCoord4sv DO_NOT_USE_glMultiTexCoord4sv - -// GL Version 1.4 -#undef glFogCoordPointer -#define glFogCoordPointer DO_NOT_USE_glFogCoordPointer -#undef glFogCoordd -#define glFogCoordd DO_NOT_USE_glFogCoordd -#undef glFogCoorddv -#define glFogCoorddv DO_NOT_USE_glFogCoorddv -#undef glFogCoordf -#define glFogCoordf DO_NOT_USE_glFogCoordf -#undef glFogCoordfv -#define glFogCoordfv DO_NOT_USE_glFogCoordfv -#undef glSecondaryColor3b -#define glSecondaryColor3b DO_NOT_USE_glSecondaryColor3b -#undef glSecondaryColor3bv -#define glSecondaryColor3bv DO_NOT_USE_glSecondaryColor3bv -#undef glSecondaryColor3d -#define glSecondaryColor3d DO_NOT_USE_glSecondaryColor3d -#undef glSecondaryColor3dv -#define glSecondaryColor3dv DO_NOT_USE_glSecondaryColor3dv -#undef glSecondaryColor3f -#define glSecondaryColor3f DO_NOT_USE_glSecondaryColor3f -#undef glSecondaryColor3fv -#define glSecondaryColor3fv DO_NOT_USE_glSecondaryColor3fv -#undef glSecondaryColor3i -#define glSecondaryColor3i DO_NOT_USE_glSecondaryColor3i -#undef glSecondaryColor3iv -#define glSecondaryColor3iv DO_NOT_USE_glSecondaryColor3iv -#undef glSecondaryColor3s -#define glSecondaryColor3s DO_NOT_USE_glSecondaryColor3s -#undef glSecondaryColor3sv -#define glSecondaryColor3sv DO_NOT_USE_glSecondaryColor3sv -#undef glSecondaryColor3ub -#define glSecondaryColor3ub DO_NOT_USE_glSecondaryColor3ub -#undef glSecondaryColor3ubv -#define glSecondaryColor3ubv DO_NOT_USE_glSecondaryColor3ubv -#undef glSecondaryColor3ui -#define glSecondaryColor3ui DO_NOT_USE_glSecondaryColor3ui -#undef glSecondaryColor3uiv -#define glSecondaryColor3uiv DO_NOT_USE_glSecondaryColor3uiv -#undef glSecondaryColor3us -#define glSecondaryColor3us DO_NOT_USE_glSecondaryColor3us -#undef glSecondaryColor3usv -#define glSecondaryColor3usv DO_NOT_USE_glSecondaryColor3usv -#undef glSecondaryColorPointer -#define glSecondaryColorPointer DO_NOT_USE_glSecondaryColorPointer -#undef glWindowPos2d -#define glWindowPos2d DO_NOT_USE_glWindowPos2d -#undef glWindowPos2dv -#define glWindowPos2dv DO_NOT_USE_glWindowPos2dv -#undef glWindowPos2f -#define glWindowPos2f DO_NOT_USE_glWindowPos2f -#undef glWindowPos2fv -#define glWindowPos2fv DO_NOT_USE_glWindowPos2fv -#undef glWindowPos2i -#define glWindowPos2i DO_NOT_USE_glWindowPos2i -#undef glWindowPos2iv -#define glWindowPos2iv DO_NOT_USE_glWindowPos2iv -#undef glWindowPos2s -#define glWindowPos2s DO_NOT_USE_glWindowPos2s -#undef glWindowPos2sv -#define glWindowPos2sv DO_NOT_USE_glWindowPos2sv -#undef glWindowPos3d -#define glWindowPos3d DO_NOT_USE_glWindowPos3d -#undef glWindowPos3dv -#define glWindowPos3dv DO_NOT_USE_glWindowPos3dv -#undef glWindowPos3f -#define glWindowPos3f DO_NOT_USE_glWindowPos3f -#undef glWindowPos3fv -#define glWindowPos3fv DO_NOT_USE_glWindowPos3fv -#undef glWindowPos3i -#define glWindowPos3i DO_NOT_USE_glWindowPos3i -#undef glWindowPos3iv -#define glWindowPos3iv DO_NOT_USE_glWindowPos3iv -#undef glWindowPos3s -#define glWindowPos3s DO_NOT_USE_glWindowPos3s -#undef glWindowPos3sv -#define glWindowPos3sv DO_NOT_USE_glWindowPos3sv - -// Old Token Names 1.2 -#undef GL_POINT_SIZE_RANGE -#define GL_POINT_SIZE_RANGE DO_NOT_USE_GL_POINT_SIZE_RANGE -#undef GL_POINT_SIZE_GRANULARITY -#define GL_POINT_SIZE_GRANULARITY DO_NOT_USE_GL_POINT_SIZE_GRANULARITY - -// Old Token Names 1.5 -#undef GL_CURRENT_FOG_COORDINATE -#define GL_CURRENT_FOG_COORDINATE DO_NOT_USE_GL_CURRENT_FOG_COORDINATE -#undef GL_FOG_COORDINATE -#define GL_FOG_COORDINATE DO_NOT_USE_GL_FOG_COORDINATE -#undef GL_FOG_COORDINATE_ARRAY -#define GL_FOG_COORDINATE_ARRAY DO_NOT_USE_GL_FOG_COORDINATE_ARRAY -#undef GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING -#undef GL_FOG_COORDINATE_ARRAY_POINTER -#define GL_FOG_COORDINATE_ARRAY_POINTER DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_POINTER -#undef GL_FOG_COORDINATE_ARRAY_STRIDE -#define GL_FOG_COORDINATE_ARRAY_STRIDE DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_STRIDE -#undef GL_FOG_COORDINATE_ARRAY_TYPE -#define GL_FOG_COORDINATE_ARRAY_TYPE DO_NOT_USE_GL_FOG_COORDINATE_ARRAY_TYPE -#undef GL_FOG_COORDINATE_SOURCE -#define GL_FOG_COORDINATE_SOURCE DO_NOT_USE_GL_FOG_COORDINATE_SOURCE -#undef GL_SOURCE0_ALPHA -#define GL_SOURCE0_ALPHA DO_NOT_USE_GL_SOURCE0_ALPHA -#undef GL_SOURCE0_RGB -#define GL_SOURCE0_RGB DO_NOT_USE_GL_SOURCE0_RGB -#if 0 /* Those are reused as new valid enum! GL_SRC1_COLOR etc... */ -# undef GL_SOURCE1_ALPHA -# define GL_SOURCE1_ALPHA DO_NOT_USE_GL_SOURCE1_ALPHA -# undef GL_SOURCE1_RGB -# define GL_SOURCE1_RGB DO_NOT_USE_GL_SOURCE1_RGB -#endif -#undef GL_SOURCE2_ALPHA -#define GL_SOURCE2_ALPHA DO_NOT_USE_GL_SOURCE2_ALPHA -#undef GL_SOURCE2_RGB -#define GL_SOURCE2_RGB DO_NOT_USE_GL_SOURCE2_RGB - -#if 0 /* Those are deprecated but still valid */ -// Old Token Names 3.0 -# undef GL_CLIP_PLANE0 -# define GL_CLIP_PLANE0 USE_GL_CLIP_DISTANCE0 -# undef GL_CLIP_PLANE1 -# define GL_CLIP_PLANE1 USE_GL_CLIP_DISTANCE1 -# undef GL_CLIP_PLANE2 -# define GL_CLIP_PLANE2 USE_GL_CLIP_DISTANCE2 -# undef GL_CLIP_PLANE3 -# define GL_CLIP_PLANE3 USE_GL_CLIP_DISTANCE3 -# undef GL_CLIP_PLANE4 -# define GL_CLIP_PLANE4 USE_GL_CLIP_DISTANCE4 -# undef GL_CLIP_PLANE5 -# define GL_CLIP_PLANE5 USE_GL_CLIP_DISTANCE5 -# undef GL_COMPARE_R_TO_TEXTURE -# define GL_COMPARE_R_TO_TEXTURE USE_GL_COMPARE_REF_TO_TEXTURE -# undef GL_MAX_CLIP_PLANES -# define GL_MAX_CLIP_PLANES USE_GL_MAX_CLIP_DISTANCES -# undef GL_MAX_VARYING_FLOATS -# define GL_MAX_VARYING_FLOATS USE__MAX_VARYING_COMPONENTS - -// Old Token Names 3.2 -# undef GL_VERTEX_PROGRAM_POINT_SIZE -# define GL_VERTEX_PROGRAM_POINT_SIZE USE_GL_PROGRAM_POINT_SIZE -#endif - -#endif /* __GL_DEPRECATED_H__ */ diff --git a/intern/glew-mx/intern/glew-mx.c b/intern/glew-mx/intern/glew-mx.c deleted file mode 100644 index c6992c8ae25..00000000000 --- a/intern/glew-mx/intern/glew-mx.c +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2014 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup intern_glew-mx - */ - -#include "glew-mx.h" - -#include <stdio.h> -#include <stdlib.h> - -#define CASE_CODE_RETURN_STR(code) \ - case code: \ - return #code; - -static const char *get_glew_error_enum_string(GLenum error) -{ - switch (error) { - CASE_CODE_RETURN_STR(GLEW_OK) /* also GLEW_NO_ERROR */ - CASE_CODE_RETURN_STR(GLEW_ERROR_NO_GL_VERSION) - CASE_CODE_RETURN_STR(GLEW_ERROR_GL_VERSION_10_ONLY) - CASE_CODE_RETURN_STR(GLEW_ERROR_GLX_VERSION_11_ONLY) -#ifdef WITH_GLEW_ES - CASE_CODE_RETURN_STR(GLEW_ERROR_NOT_GLES_VERSION) - CASE_CODE_RETURN_STR(GLEW_ERROR_GLES_VERSION) - CASE_CODE_RETURN_STR(GLEW_ERROR_NO_EGL_VERSION) - CASE_CODE_RETURN_STR(GLEW_ERROR_EGL_VERSION_10_ONLY) -#endif - default: - return NULL; - } -} - -GLenum glew_chk(GLenum error, const char *file, int line, const char *text) -{ - if (error != GLEW_OK) { - const char *code = get_glew_error_enum_string(error); - const char *msg = (const char *)glewGetErrorString(error); - - if (error == GLEW_ERROR_NO_GL_VERSION) - return GLEW_OK; - -#ifndef NDEBUG - fprintf(stderr, - "%s(%d):[%s] -> GLEW Error (0x%04X): %s: %s\n", - file, - line, - text, - error, - code ? code : "<no symbol>", - msg ? msg : "<no message>"); -#else - (void)file; - (void)line; - (void)text; - fprintf(stderr, - "GLEW Error (0x%04X): %s: %s\n", - error, - code ? code : "<no symbol>", - msg ? msg : "<no message>"); -#endif - } - - return error; -} diff --git a/intern/glew-mx/intern/symbol-binding.h b/intern/glew-mx/intern/symbol-binding.h deleted file mode 100644 index b7993993739..00000000000 --- a/intern/glew-mx/intern/symbol-binding.h +++ /dev/null @@ -1,275 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2014 Blender Foundation. All rights reserved. */ - -/** \file - * \ingroup intern_glew-mx - * - * This file is for any simple stuff that is missing from GLEW when - * compiled with either the GLEW_ES_ONLY or the GLEW_NO_ES flag. - * - * Should be limited to symbolic constants. - * - * This file is NOT for checking DEPRECATED OpenGL symbolic constants. - */ - -#ifndef __SYMBOL_BINDING_H__ -#define __SYMBOL_BINDING_H__ - -#ifndef __GLEW_MX_H__ -# error This file is meant to be included from glew-mx.h -#endif - -#ifdef GLEW_ES_ONLY - -/* ES does not support the GLdouble type. */ -# ifndef GLdouble -# define GLdouble double -# endif - -/* - * Need stubs for these version checks if compiling with only ES support. - * Rely on compiler to eliminate unreachable code when version checks become constants. - */ - -# ifndef GLEW_VERSION_1_1 -# define GLEW_VERSION_1_1 0 -# endif - -# ifndef GLEW_VERSION_1_2 -# define GLEW_VERSION_1_2 0 -# endif - -# ifndef GLEW_VERSION_1_3 -# define GLEW_VERSION_1_3 0 -# endif - -# ifndef GLEW_VERSION_1_4 -# define GLEW_VERSION_1_4 0 -# endif - -# ifndef GLEW_VERSION_1_5 -# define GLEW_VERSION_1_5 0 -# endif - -# ifndef GLEW_VERSION_2_0 -# define GLEW_VERSION_2_0 0 -# endif - -# ifndef GLEW_VERSION_3_0 -# define GLEW_VERSION_3_0 0 -# endif - -# ifndef GLEW_ARB_shader_objects -# define GLEW_ARB_shader_objects 0 -# endif - -# ifndef GLEW_ARB_vertex_shader -# define GLEW_ARB_vertex_shader 0 -# endif - -# ifndef GLEW_ARB_vertex_program -# define GLEW_ARB_vertex_program 0 -# endif - -# ifndef GLEW_ARB_fragment_program -# define GLEW_ARB_fragment_program 0 -# endif - -# ifndef GLEW_ARB_vertex_buffer_object -# define GLEW_ARB_vertex_buffer_object 0 -# endif - -# ifndef GLEW_ARB_framebuffer_object -# define GLEW_ARB_framebuffer_object 0 -# endif - -# ifndef GLEW_ARB_multitexture -# define GLEW_ARB_multitexture 0 -# endif - -# ifndef GLEW_EXT_framebuffer_object -# define GLEW_EXT_framebuffer_object 0 -# endif - -# ifndef GLEW_ARB_depth_texture -# define GLEW_ARB_depth_texture 0 -# endif - -# ifndef GLEW_ARB_shadow -# define GLEW_ARB_shadow 0 -# endif - -# ifndef GLEW_ARB_texture_float -# define GLEW_ARB_texture_float 0 -# endif - -# ifndef GLEW_ARB_texture_non_power_of_two -# define GLEW_ARB_texture_non_power_of_two 0 -# endif - -# ifndef GLEW_ARB_texture3D -# define GLEW_ARB_texture3D 0 -# endif - -# ifndef GLEW_EXT_texture3D -# define GLEW_EXT_texture3D 0 -# endif - -# ifndef GLEW_ARB_texture_rg -# define GLEW_ARB_texture_rg 0 -# endif - -# ifndef GLEW_ARB_texture_query_lod -# define GLEW_ARB_texture_query_lod 0 -# endif - -/* - * The following symbolic constants are missing from an ES only header, - * so alias them to their (same valued) extension versions which are available in the header. - * - * Be careful that this does not lead to unguarded use of what are extensions in ES! - * - * Some of these may be here simply to patch inconsistencies in the header files. - */ - -# ifndef GL_TEXTURE_3D -# define GL_TEXTURE_3D GL_TEXTURE_3D_OES -# endif - -# ifndef GL_TEXTURE_WRAP_R -# define GL_TEXTURE_WRAP_R GL_TEXTURE_WRAP_R_OES -# endif - -# ifndef GL_TEXTURE_COMPARE_MODE -# define GL_TEXTURE_COMPARE_MODE GL_TEXTURE_COMPARE_MODE_EXT -# endif - -# ifndef GL_COMPARE_REF_TO_TEXTURE -# define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_REF_TO_TEXTURE_EXT -# endif - -# ifndef GL_TEXTURE_COMPARE_FUNC -# define GL_TEXTURE_COMPARE_FUNC GL_TEXTURE_COMPARE_FUNC_EXT -# endif - -# ifndef GL_RGBA8 -# define GL_RGBA8 GL_RGBA8_OES -# endif - -# ifndef GL_RGBA16F -# define GL_RGBA16F GL_RGBA16F_EXT -# endif - -# ifndef GL_RG32F -# define GL_RG32F GL_RG32F_EXT -# endif - -# ifndef GL_RGB8 -# define GL_RGB8 GL_RGB8_OES -# endif - -# ifndef GL_RG -# define GL_RG GL_RG_EXT -# endif - -# ifndef GL_RED -# define GL_RED GL_RED_EXT -# endif - -# ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS -# define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES -# endif - -# ifndef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER -# define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES -# endif - -# ifndef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER -# define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES -# endif - -# ifndef GL_WRITE_ONLY -# define GL_WRITE_ONLY GL_WRITE_ONLY_OES -# endif - -# ifndef GLEW_ARB_vertex_array_object -# define GLEW_ARB_vertex_array_object 0 -# endif - -/* end of ifdef GLEW_ES_ONLY */ -#elif defined(GLEW_NO_ES) - -/* - * Need stubs for these version checks if compiling without any support. - * Rely on compiler to eliminate unreachable code when version checks become constants - */ - -# ifndef GLEW_ES_VERSION_2_0 -# define GLEW_ES_VERSION_2_0 0 -# endif - -# ifndef GLEW_EXT_texture_storage -# define GLEW_EXT_texture_storage 0 -# endif - -# ifndef GLEW_OES_framebuffer_object -# define GLEW_OES_framebuffer_object 0 -# endif - -# ifndef GLEW_OES_mapbuffer -# define GLEW_OES_mapbuffer 0 -# endif - -# ifndef GLEW_OES_required_internalformat -# define GLEW_OES_required_internalformat 0 -# endif - -# ifndef GLEW_EXT_color_buffer_half_float -# define GLEW_EXT_color_buffer_half_float 0 -# endif - -# ifndef GLEW_OES_depth_texture -# define GLEW_OES_depth_texture 0 -# endif - -# ifndef GLEW_EXT_shadow_samplers -# define GLEW_EXT_shadow_samplers 0 -# endif - -# ifndef GLEW_ARB_texture3D -# define GLEW_ARB_texture3D 0 -# endif - -# ifndef GLEW_OES_texture_3D -# define GLEW_OES_texture_3D 0 -# endif - -# ifndef GLEW_EXT_texture_rg -# define GLEW_EXT_texture_rg 0 -# endif - -# ifndef GLEW_OES_vertex_array_object -# define GLEW_OES_vertex_array_object 0 -# endif - -/* - * The following symbolic constants are missing when there is no ES support, - * so alias them to their (same valued) extension versions which are available in the header. - * - * Desktop GL typically does not have any extensions that originated from ES, - * unlike ES which has many extensions to replace what was taken out. - * - * For that reason these aliases are more likely just patching inconsistencies in the header files. - */ - -# ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS -# define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT -# endif - -# ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS -# define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT -# endif - -#endif /* ifdef GLEW_NO_ES */ - -#endif /* __SYMBOL_BINDING_H__*/ diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt index 3329e4bf10e..89fdf367037 100644 --- a/intern/guardedalloc/CMakeLists.txt +++ b/intern/guardedalloc/CMakeLists.txt @@ -1,6 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright 2006 Blender Foundation. All rights reserved. +if(HAVE_MALLOC_STATS_H) + add_definitions(-DHAVE_MALLOC_STATS_H) +endif() + set(INC . ../atomic diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index fca19fb9731..64987548a11 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -199,6 +199,15 @@ extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT; #ifndef NDEBUG extern const char *(*MEM_name_ptr)(void *vmemh); +/** + * Change the debugging name/string assigned to the memory allocated at \a vmemh. Only affects the + * guarded allocator. The name must be a static string, because only a pointer to it is stored! + * + * Handy when debugging leaking memory allocated by some often called, generic function with a + * unspecific name. A caller with more info can set a more specific name, and see which call to the + * generic function allocates the leaking memory. + */ +extern void (*MEM_name_ptr_set)(void *vmemh, const char *str) ATTR_NONNULL(); #endif /** diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index f7979168799..63f06ced31d 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -49,6 +49,7 @@ size_t (*MEM_get_peak_memory)(void) = MEM_lockfree_get_peak_memory; #ifndef NDEBUG const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr; +void (*MEM_name_ptr_set)(void *vmemh, const char *str) = MEM_lockfree_name_ptr_set; #endif void *aligned_malloc(size_t size, size_t alignment) @@ -128,6 +129,7 @@ void MEM_use_lockfree_allocator(void) #ifndef NDEBUG MEM_name_ptr = MEM_lockfree_name_ptr; + MEM_name_ptr_set = MEM_lockfree_name_ptr_set; #endif } @@ -159,5 +161,6 @@ void MEM_use_guarded_allocator(void) #ifndef NDEBUG MEM_name_ptr = MEM_guarded_name_ptr; + MEM_name_ptr_set = MEM_guarded_name_ptr_set; #endif } diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c index 8bf1680e6f8..cd4b99ecde8 100644 --- a/intern/guardedalloc/intern/mallocn_guarded_impl.c +++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c @@ -1199,4 +1199,18 @@ const char *MEM_guarded_name_ptr(void *vmemh) return "MEM_guarded_name_ptr(NULL)"; } + +void MEM_guarded_name_ptr_set(void *vmemh, const char *str) +{ + if (!vmemh) { + return; + } + + MemHead *memh = vmemh; + memh--; + memh->name = str; + if (memh->prev) { + MEMNEXT(memh->prev)->nextname = str; + } +} #endif /* NDEBUG */ diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h index f8b16ff6ddf..1e9883f42c8 100644 --- a/intern/guardedalloc/intern/mallocn_intern.h +++ b/intern/guardedalloc/intern/mallocn_intern.h @@ -17,8 +17,7 @@ #undef HAVE_MALLOC_STATS #define USE_MALLOC_USABLE_SIZE /* internal, when we have malloc_usable_size() */ -#if defined(__linux__) || (defined(__FreeBSD_kernel__) && !defined(__FreeBSD__)) || \ - defined(__GLIBC__) +#if defined(HAVE_MALLOC_STATS_H) # include <malloc.h> # define HAVE_MALLOC_STATS #elif defined(__FreeBSD__) @@ -131,6 +130,7 @@ void MEM_lockfree_reset_peak_memory(void); size_t MEM_lockfree_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT; #ifndef NDEBUG const char *MEM_lockfree_name_ptr(void *vmemh); +void MEM_lockfree_name_ptr_set(void *vmemh, const char *str); #endif /* Prototypes for fully guarded allocator functions */ @@ -174,6 +174,7 @@ void MEM_guarded_reset_peak_memory(void); size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT; #ifndef NDEBUG const char *MEM_guarded_name_ptr(void *vmemh); +void MEM_guarded_name_ptr_set(void *vmemh, const char *str); #endif #ifdef __cplusplus diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c index 300e2000a14..b5ee539ff4d 100644 --- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c +++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c @@ -426,4 +426,8 @@ const char *MEM_lockfree_name_ptr(void *vmemh) return "MEM_lockfree_name_ptr(NULL)"; } + +void MEM_lockfree_name_ptr_set(void *UNUSED(vmemh), const char *UNUSED(str)) +{ +} #endif /* NDEBUG */ diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index fc14c909f4d..f5f22dc700b 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -626,7 +626,7 @@ static void manta_python_main_module_restore(PyObject *main_mod) * access these variables, the same __main__ module has to be used every time. * * Unfortunately, we also depend on the fact that mantaflow dumps variables into this module using - * PyRun_SimpleString. So we can't easily create a separate module without changing mantaflow. + * #PyRun_String. So we can't easily create a separate module without changing mantaflow. */ static PyObject *manta_main_module = nullptr; @@ -1161,7 +1161,7 @@ string MANTA::parseScript(const string &setup_string, FluidModifierData *fmd) return res.str(); } -/* Dirty hack: Needed to format paths from python code that is run via PyRun_SimpleString */ +/** Dirty hack: Needed to format paths from python code that is run via #PyRun_String. */ static string escapePath(string const &s) { string result = ""; diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index be6ccc5c2c5..8fe478d35c1 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -3,7 +3,6 @@ set(INC . - ../glew-mx ../guardedalloc ../../source/blender/blenlib ../../source/blender/gpu @@ -32,12 +31,11 @@ if(WITH_OPENCOLORIO) -DWITH_OCIO ) - add_definitions(${GL_DEFINITIONS}) add_definitions(${OPENCOLORIO_DEFINITIONS}) list(APPEND INC_SYS ${OPENCOLORIO_INCLUDE_DIRS} - ${GLEW_INCLUDE_PATH} + ${Epoxy_INCLUDE_DIRS} ) list(APPEND SRC diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt index 14cc6a70cd5..596534fc82c 100644 --- a/intern/opensubdiv/CMakeLists.txt +++ b/intern/opensubdiv/CMakeLists.txt @@ -29,7 +29,7 @@ if(WITH_OPENSUBDIV) list(APPEND INC_SYS ${OPENSUBDIV_INCLUDE_DIRS} - ${GLEW_INCLUDE_PATH} + ${Epoxy_INCLUDE_DIRS} ) list(APPEND SRC @@ -87,9 +87,6 @@ if(WITH_OPENSUBDIV) OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK) OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE) - add_definitions(${GL_DEFINITIONS}) - add_definitions(-DOSD_USES_GLEW) - if(WIN32) add_definitions(-DNOMINMAX) add_definitions(-D_USE_MATH_DEFINES) diff --git a/intern/opensubdiv/internal/evaluator/gl_compute_evaluator.cc b/intern/opensubdiv/internal/evaluator/gl_compute_evaluator.cc index c2ab2a522d2..148770b0d39 100644 --- a/intern/opensubdiv/internal/evaluator/gl_compute_evaluator.cc +++ b/intern/opensubdiv/internal/evaluator/gl_compute_evaluator.cc @@ -22,9 +22,23 @@ // language governing permissions and limitations under the Apache License. // -#include "gl_compute_evaluator.h" +#include <epoxy/gl.h> + +/* There are few aspects here: + * - macOS is strict about including both gl.h and gl3.h + * - libepoxy only pretends to be a replacement for gl.h + * - OpenSubdiv internally uses `OpenGL/gl3.h` on macOS + * + * In order to silence the warning pretend that gl3 has been included, fully relying on symbols + * from the epoxy. + * + * This works differently from how OpenSubdiv internally will use `OpenGL/gl3.h` without epoxy. + * Sounds fragile, but so far things seems to work. */ +#if defined(__APPLE__) +# define __gl3_h_ +#endif -#include <GL/glew.h> +#include "gl_compute_evaluator.h" #include <opensubdiv/far/error.h> #include <opensubdiv/far/patchDescriptor.h> @@ -57,7 +71,7 @@ template<class T> GLuint createSSBO(std::vector<T> const &src) GLuint devicePtr = 0; #if defined(GL_ARB_direct_state_access) - if (GLEW_ARB_direct_state_access) { + if (epoxy_has_gl_extension("GL_ARB_direct_state_access")) { glCreateBuffers(1, &devicePtr); glNamedBufferData(devicePtr, src.size() * sizeof(T), &src.at(0), GL_STATIC_DRAW); } diff --git a/intern/opensubdiv/internal/evaluator/patch_map.h b/intern/opensubdiv/internal/evaluator/patch_map.h index af804d6ca71..1cb9400245f 100644 --- a/intern/opensubdiv/internal/evaluator/patch_map.h +++ b/intern/opensubdiv/internal/evaluator/patch_map.h @@ -126,7 +126,7 @@ class PatchMap { // Internal methods supporting quadtree construction and queries void assignRootNode(QuadNode *node, int index); - QuadNode *assignLeafOrChildNode(QuadNode *node, bool isLeaf, int quad, int index); + QuadNode *assignLeafOrChildNode(QuadNode *node, bool isLeaf, int quadrant, int index); template<class T> static int transformUVToQuadQuadrant(T const &median, T &u, T &v); template<class T> |