diff options
Diffstat (limited to 'intern')
107 files changed, 1892 insertions, 1289 deletions
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt index 7fecb1a48a7..b3682a77875 100644 --- a/intern/audaspace/CMakeLists.txt +++ b/intern/audaspace/CMakeLists.txt @@ -164,6 +164,8 @@ set(SRC intern/AUD_SequencerHandle.h intern/AUD_SequencerReader.cpp intern/AUD_SequencerReader.h + intern/AUD_Set.cpp + intern/AUD_Set.h intern/AUD_SilenceFactory.cpp intern/AUD_SilenceFactory.h intern/AUD_SilenceReader.cpp diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 48a3c7b2ded..341f1cd3f6b 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -41,7 +41,6 @@ # include "AUD_PyAPI.h" #endif -#include <set> #include <cstdlib> #include <cstring> #include <cmath> @@ -814,10 +813,9 @@ int AUD_Device_read(AUD_Device *device, data_t *buffer, int length) void AUD_Device_free(AUD_Device *device) { - assert(device); - try { - delete device; + if(device != &AUD_device) + delete device; } catch(AUD_Exception&) { @@ -1225,44 +1223,6 @@ void AUD_Handle_free(AUD_Handle *handle) delete handle; } -void *AUD_createSet() -{ - return new std::set<void *>(); -} - -void AUD_destroySet(void *set) -{ - delete reinterpret_cast<std::set<void *>*>(set); -} - -char AUD_removeSet(void *set, void *entry) -{ - if (set) - return reinterpret_cast<std::set<void *>*>(set)->erase(entry); - return 0; -} - -void AUD_addSet(void *set, void *entry) -{ - if (entry) - reinterpret_cast<std::set<void *>*>(set)->insert(entry); -} - -void *AUD_getSet(void *set) -{ - if (set) { - std::set<void *>* rset = reinterpret_cast<std::set<void *>*>(set); - if (!rset->empty()) { - std::set<void *>::iterator it = rset->begin(); - void *result = *it; - rset->erase(it); - return result; - } - } - - return NULL; -} - const char *AUD_mixdown(AUD_Sound *sound, unsigned int start, unsigned int length, unsigned int buffersize, const char *filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate) { try { @@ -1347,6 +1307,11 @@ AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, f } } +AUD_Device *AUD_Device_getCurrent(void) +{ + return &AUD_device; +} + int AUD_isJackSupported(void) { #ifdef WITH_JACK diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index f53dfcefedd..bdbe751b140 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -811,6 +811,8 @@ extern void *AUD_getPythonSound(AUD_Sound *sound); extern AUD_Sound *AUD_getSoundFromPython(void *sound); #endif +extern AUD_Device *AUD_Device_getCurrent(void); + extern int AUD_isJackSupported(void); #ifdef __cplusplus diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index c936b900d75..030f0dbbf14 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -30,8 +30,8 @@ def _is_using_buggy_driver(): version = bgl.glGetString(bgl.GL_VERSION) if version.endswith("Compatibility Profile Context"): # Old HD 4xxx and 5xxx series drivers did not have driver version - # in the version string, but thsoe cards do not quite work and - # cusing crashes. + # in the version string, but those cards do not quite work and + # causing crashes. return True regex = re.compile(".*Compatibility Profile Context ([0-9]+(\.[0-9]+)+)$") if not regex.match(version): @@ -49,12 +49,13 @@ def _workaround_buggy_drivers(): print("Cycles: OpenGL driver known to be buggy, disabling OpenCL platform.") _cycles.opencl_disable() + def init(): import bpy import _cycles import os.path - # Workaroud posibly buggy legacy drivers which crashes on the OpenCL + # Workaround possibly buggy legacy drivers which crashes on the OpenCL # device enumeration. # # This checks are not really correct because they might still fail diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 3417435fcbd..c3139831ca2 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -463,11 +463,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Use BVH spatial splits: longer builder time, faster render", default=False, ) - cls.use_cache = BoolProperty( - name="Cache BVH", - description="Cache last built BVH to disk for faster re-render if no geometry changed", - default=False, - ) cls.tile_order = EnumProperty( name="Tile Order", description="Tile order for rendering", @@ -524,6 +519,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): min=0.0, max=5.0 ) + cls.motion_blur_position = EnumProperty( + name="Motion Blur Position", + default='CENTER', + description="Offset for the shutter's time interval, allows to change the motion blur trails", + items=( + ('START', "Start on Frame", "The shutter opens at the current frame"), + ('CENTER', "Center on Frame", "The shutter is open during the current frame"), + ('END', "End on Frame", "The shutter closes at the current frame"), + ), + ) + @classmethod def unregister(cls): del bpy.types.Scene.cycles @@ -743,7 +749,7 @@ class CyclesWorldSettings(bpy.types.PropertyGroup): name="Map Resolution", description="Importance map size is resolution x resolution; " "higher values potentially produce less noise, at the cost of memory and speed", - min=4, max=8096, + min=4, max=8192, default=256, ) cls.samples = IntProperty( diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index fdb2afdb5e9..3700da3263e 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -259,11 +259,14 @@ class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout - rd = context.scene.render + scene = context.scene + cscene = scene.cycles + rd = scene.render layout.active = rd.use_motion_blur - row = layout.row() - row.prop(rd, "motion_blur_shutter") + col = layout.column() + col.prop(cscene, "motion_blur_position", text="Position") + col.prop(rd, "motion_blur_shutter") class CyclesRender_PT_film(CyclesButtonsPanel, Panel): @@ -332,7 +335,6 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): col.separator() col.label(text="Final Render:") - col.prop(cscene, "use_cache") col.prop(rd, "use_persistent_data", text="Persistent Images") col.separator() @@ -438,6 +440,7 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel): class CyclesRender_PT_views(CyclesButtonsPanel, Panel): bl_label = "Views" bl_context = "render_layer" + bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): rd = context.scene.render @@ -1163,13 +1166,17 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel): col.prop(mat, "alpha") col.separator() - col.prop(mat, "pass_index") + col.label("Viewport Alpha:") + col.prop(mat.game_settings, "alpha_blend", text="") col = split.column(align=True) col.label("Viewport Specular:") col.prop(mat, "specular_color", text="") col.prop(mat, "specular_hardness", text="Hardness") + col.separator() + col.prop(mat, "pass_index") + class CyclesTexture_PT_context(CyclesButtonsPanel, Panel): bl_label = "" diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 0a79bfbf793..491b5632ed5 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -36,6 +36,7 @@ struct BlenderCamera { float lens; float shuttertime; + Camera::MotionPosition motion_position; float aperturesize; uint apertureblades; @@ -83,6 +84,7 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render bcam->sensor_height = 18.0f; bcam->sensor_fit = BlenderCamera::AUTO; bcam->shuttertime = 1.0f; + bcam->motion_position = Camera::MOTION_POSITION_CENTER; bcam->border.right = 1.0f; bcam->border.top = 1.0f; bcam->pano_viewplane.right = 1.0f; @@ -107,9 +109,9 @@ static float blender_camera_focal_distance(BL::RenderEngine b_engine, BL::Object b_engine.camera_model_matrix(b_ob, b_ob_matrix); Transform obmat = get_transform(b_ob_matrix); Transform dofmat = get_transform(b_dof_object.matrix_world()); - Transform mat = transform_inverse(obmat) * dofmat; - - return fabsf(transform_get_column(&mat, 3).z); + float3 view_dir = normalize(transform_get_column(&obmat, 2)); + float3 dof_dir = transform_get_column(&obmat, 3) - transform_get_column(&dofmat, 3); + return fabsf(dot(view_dir, dof_dir)); } static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Object b_ob, bool skip_panorama = false) @@ -409,6 +411,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->shuttertime = bcam->shuttertime; cam->fov_pre = cam->fov; cam->fov_post = cam->fov; + cam->motion_position = bcam->motion_position; /* border */ cam->border = bcam->border; @@ -431,6 +434,22 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override bcam.pixelaspect.y = b_render.pixel_aspect_y(); bcam.shuttertime = b_render.motion_blur_shutter(); + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); + switch(RNA_enum_get(&cscene, "motion_blur_position")) { + case 0: + bcam.motion_position = Camera::MOTION_POSITION_START; + break; + case 1: + bcam.motion_position = Camera::MOTION_POSITION_CENTER; + break; + case 2: + bcam.motion_position = Camera::MOTION_POSITION_END; + break; + default: + bcam.motion_position = Camera::MOTION_POSITION_CENTER; + break; + } + /* border */ if(b_render.use_border()) { bcam.border.left = b_render.border_min_x(); @@ -487,6 +506,11 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings b_render, BlenderCamera bcam; float aspectratio, sensor_size; blender_camera_init(&bcam, b_render); + + /* TODO(sergey): Consider making it a part of blender_camera_init(). */ + bcam.pixelaspect.x = b_render.pixel_aspect_x(); + bcam.pixelaspect.y = b_render.pixel_aspect_y(); + blender_camera_from_object(&bcam, b_engine, b_ob); blender_camera_viewplane(&bcam, width, height, diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index dba801fc4df..6a119081bfd 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -145,7 +145,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f); int totcurves = totchild; - if(b_part.child_type() == 0) + if(b_part.child_type() == 0 || totchild == 0) totcurves += totparts; if(totcurves == 0) @@ -169,7 +169,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip")); int pa_no = 0; - if(!(b_part.child_type() == 0)) + if(!(b_part.child_type() == 0) && totchild != 0) pa_no = totparts; int num_add = (totparts+totchild - pa_no); @@ -233,14 +233,14 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f); int totcurves = totchild; - if(b_part.child_type() == 0) + if(b_part.child_type() == 0 || totchild == 0) totcurves += totparts; if(totcurves == 0) continue; int pa_no = 0; - if(!(b_part.child_type() == 0)) + if(!(b_part.child_type() == 0) && totchild != 0) pa_no = totparts; int num_add = (totparts+totchild - pa_no); @@ -287,14 +287,14 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f); int totcurves = totchild; - if(b_part.child_type() == 0) + if(b_part.child_type() == 0 || totchild == 0) totcurves += totparts; if(totcurves == 0) continue; int pa_no = 0; - if(!(b_part.child_type() == 0)) + if(!(b_part.child_type() == 0) && totchild != 0) pa_no = totparts; int num_add = (totparts+totchild - pa_no); diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index e81170ac411..c2ccef548c7 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -85,7 +85,7 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float BL::MeshTextureFace tf = userdata->layer->data[face_num]; float3 tfuv; - switch (vert_num) { + switch(vert_num) { case 0: tfuv = get_float3(tf.uv1()); break; @@ -842,6 +842,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion return; } + /* TODO(sergey): Perform preliminary check for number of verticies. */ if(numverts) { /* find attributes */ Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); @@ -873,7 +874,9 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion /* in case of new attribute, we verify if there really was any motion */ if(new_attribute) { - if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) { + if(b_mesh.vertices.length() != numverts || + memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) + { /* no motion, remove attributes again */ VLOG(1) << "No actual deformation motion for object " << b_ob.name(); mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION); diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 432c4aaa078..11593807a00 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -558,11 +558,20 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time) bool cancel = false; bool use_portal = false; + uint layer_override = get_layer(b_engine.layer_override()); for(; b_sce && !cancel; b_sce = b_sce.background_set()) { + /* Render layer's scene_layer is affected by local view already, + * which is not a desired behavior here. + */ + uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers()); for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) { BL::Object b_ob = b_base->object(); bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render(); - uint ob_layer = get_layer(b_base->layers(), b_base->layers_local_view(), render_layer.use_localview, object_is_light(b_ob)); + uint ob_layer = get_layer(b_base->layers(), + b_base->layers_local_view(), + render_layer.use_localview, + object_is_light(b_ob), + scene_layers); hide = hide || !(ob_layer & scene_layer); if(!hide) { @@ -676,6 +685,28 @@ void BlenderSync::sync_motion(BL::RenderSettings b_render, Camera prevcam = *(scene->camera); int frame_center = b_scene.frame_current(); + float frame_center_delta = 0.0f; + + if(scene->need_motion() != Scene::MOTION_PASS && + scene->camera->motion_position != Camera::MOTION_POSITION_CENTER) + { + float shuttertime = scene->camera->shuttertime; + if(scene->camera->motion_position == Camera::MOTION_POSITION_END) { + frame_center_delta = -shuttertime * 0.5f; + } + else { + assert(scene->camera->motion_position == Camera::MOTION_POSITION_START); + frame_center_delta = shuttertime * 0.5f; + } + float time = frame_center + frame_center_delta; + int frame = (int)floorf(time); + float subframe = time - frame; + python_thread_state_restore(python_thread_state); + b_engine.frame_set(frame, subframe); + python_thread_state_save(python_thread_state); + sync_camera_motion(b_render, b_cam, width, height, 0.0f); + sync_objects(b_v3d, 0.0f); + } /* always sample these times for camera motion */ motion_times.insert(-1.0f); @@ -695,7 +726,7 @@ void BlenderSync::sync_motion(BL::RenderSettings b_render, shuttertime = scene->camera->shuttertime; /* compute frame and subframe time */ - float time = frame_center + relative_time * shuttertime * 0.5f; + float time = frame_center + frame_center_delta + relative_time * shuttertime * 0.5f; int frame = (int)floorf(time); float subframe = time - frame; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 04d05ee7b3c..088748cc0ae 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -1194,7 +1194,8 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { BL::ShaderNodeTexPointDensity b_point_density_node(b_node); int length; - b_point_density_node.calc_point_density(b_scene, &length, &pixels); + int settings = background ? 1 : 0; /* 1 - render settings, 0 - vewport settings. */ + b_point_density_node.calc_point_density(b_scene, settings, &length, &pixels); } } diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 0f0be78abd8..2beeaa5e07a 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -88,7 +88,7 @@ static float3 get_node_output_vector(BL::Node b_node, const string& name) static ShaderSocketType convert_socket_type(BL::NodeSocket b_socket) { - switch (b_socket.type()) { + switch(b_socket.type()) { case BL::NodeSocket::type_VALUE: return SHADER_SOCKET_FLOAT; case BL::NodeSocket::type_INT: @@ -283,7 +283,7 @@ static ShaderNode *add_node(Scene *scene, else if(b_node.is_a(&RNA_ShaderNodeVectorTransform)) { BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); VectorTransformNode *vtransform = new VectorTransformNode(); - vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.type()]; + vtransform->type = VectorTransformNode::type_enum[b_vector_transform_node.vector_type()]; vtransform->convert_from = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_from()]; vtransform->convert_to = VectorTransformNode::convert_space_enum[b_vector_transform_node.convert_to()]; node = vtransform; @@ -332,17 +332,16 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node); AnisotropicBsdfNode *aniso = new AnisotropicBsdfNode(); - switch (b_aniso_node.distribution()) - { - case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: - aniso->distribution = ustring("Beckmann"); - break; - case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: - aniso->distribution = ustring("GGX"); - break; - case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: - aniso->distribution = ustring("Ashikhmin-Shirley"); - break; + switch(b_aniso_node.distribution()) { + case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: + aniso->distribution = ustring("Beckmann"); + break; + case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: + aniso->distribution = ustring("GGX"); + break; + case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: + aniso->distribution = ustring("Ashikhmin-Shirley"); + break; } node = aniso; @@ -633,11 +632,12 @@ static ShaderNode *add_node(Scene *scene, if(b_image.is_updated()) { scene->image_manager->tag_reload_image(env->filename, env->builtin_data, - INTERPOLATION_LINEAR, + (InterpolationType)b_env_node.interpolation(), EXTENSION_REPEAT); } } env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()]; + env->interpolation = (InterpolationType)b_env_node.interpolation(); env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()]; get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping()); node = env; @@ -767,7 +767,7 @@ static ShaderNode *add_node(Scene *scene, point_density->filename, point_density->builtin_data, point_density->interpolation, - EXTENSION_REPEAT); + EXTENSION_CLIP); } node = point_density; } @@ -1176,7 +1176,7 @@ void BlenderSync::sync_world(bool update_all) PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); /* when doing preview render check for BI's transparency settings, - * this is so because bledner's preview render routines are not able + * this is so because Blender's preview render routines are not able * to tweak all cycles's settings depending on different circumstances */ if(b_engine.is_preview() == false) diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 8888d219aac..986e90c59f7 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -161,7 +161,12 @@ void BlenderSync::sync_data(BL::RenderSettings b_render, mesh_synced.clear(); /* use for objects and motion sync */ - sync_objects(b_v3d); + if(scene->need_motion() == Scene::MOTION_PASS || + scene->need_motion() == Scene::MOTION_NONE || + scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) + { + sync_objects(b_v3d); + } sync_motion(b_render, b_v3d, b_override, @@ -427,7 +432,6 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background, bo params.bvh_type = (SceneParams::BVHType)RNA_enum_get(&cscene, "debug_bvh_type"); params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits"); - params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false; if(background && params.shadingsystem != SHADINGSYSTEM_OSL) params.persistent_data = r.use_persistent_data(); diff --git a/intern/cycles/blender/blender_texture.cpp b/intern/cycles/blender/blender_texture.cpp index cb4dd1792d0..18f66560b10 100644 --- a/intern/cycles/blender/blender_texture.cpp +++ b/intern/cycles/blender/blender_texture.cpp @@ -68,10 +68,12 @@ static void density_particle_system_texture_space( float3 particle_size = make_float3(radius, radius, radius); for(int i = 0; i < b_particle_system.particles.length(); ++i) { BL::Particle particle = b_particle_system.particles[i]; - float3 location = get_float3(particle.location()); - location = transform_point(&itfm, location); - min = ccl::min(min, location - particle_size); - max = ccl::max(max, location + particle_size); + if(particle.alive_state() == BL::Particle::alive_state_ALIVE) { + float3 location = get_float3(particle.location()); + location = transform_point(&itfm, location); + min = ccl::min(min, location - particle_size); + max = ccl::max(max, location + particle_size); + } } /* Calculate texture space from the particle bounds. */ loc = (min + max) * 0.5f; diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 165242d0dff..bd1c37a7560 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -196,7 +196,11 @@ static inline uint get_layer(BL::Array<int, 20> array) return layer; } -static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_array, bool use_local, bool is_light = false) +static inline uint get_layer(BL::Array<int, 20> array, + BL::Array<int, 8> local_array, + bool use_local, + bool is_light = false, + uint scene_layers = (1 << 20) - 1) { uint layer = 0; @@ -205,9 +209,13 @@ static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_a layer |= (1 << i); if(is_light) { - /* consider lamps on all local view layers */ - for(uint i = 0; i < 8; i++) - layer |= (1 << (20+i)); + /* Consider light is visible if it was visible without layer + * override, which matches behavior of Blender Internal. + */ + if(layer & scene_layers) { + for(uint i = 0; i < 8; i++) + layer |= (1 << (20+i)); + } } else { for(uint i = 0; i < 8; i++) diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 350ca16f6e2..4a5f8b1bda6 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -25,7 +25,6 @@ #include "bvh_node.h" #include "bvh_params.h" -#include "util_cache.h" #include "util_debug.h" #include "util_foreach.h" #include "util_logging.h" @@ -70,125 +69,12 @@ BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects) return new RegularBVH(params, objects); } -/* Cache */ - -bool BVH::cache_read(CacheData& key) -{ - key.add(system_cpu_bits()); - key.add(¶ms, sizeof(params)); - - foreach(Object *ob, objects) { - Mesh *mesh = ob->mesh; - - key.add(mesh->verts); - key.add(mesh->triangles); - key.add(mesh->curve_keys); - key.add(mesh->curves); - key.add(&ob->bounds, sizeof(ob->bounds)); - key.add(&ob->visibility, sizeof(ob->visibility)); - key.add(&mesh->transform_applied, sizeof(bool)); - - if(mesh->use_motion_blur) { - Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if(attr) - key.add(attr->buffer); - - attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if(attr) - key.add(attr->buffer); - } - } - - CacheData value; - - if(Cache::global.lookup(key, value)) { - cache_filename = key.get_filename(); - - if(!(value.read(pack.root_index) && - value.read(pack.SAH) && - value.read(pack.nodes) && - value.read(pack.leaf_nodes) && - value.read(pack.object_node) && - value.read(pack.tri_woop) && - value.read(pack.prim_type) && - value.read(pack.prim_visibility) && - value.read(pack.prim_index) && - value.read(pack.prim_object))) - { - /* Clear the pack if load failed. */ - pack.root_index = 0; - pack.SAH = 0.0f; - pack.nodes.clear(); - pack.leaf_nodes.clear(); - pack.object_node.clear(); - pack.tri_woop.clear(); - pack.prim_type.clear(); - pack.prim_visibility.clear(); - pack.prim_index.clear(); - pack.prim_object.clear(); - return false; - } - return true; - } - - return false; -} - -void BVH::cache_write(CacheData& key) -{ - CacheData value; - - value.add(pack.root_index); - value.add(pack.SAH); - - value.add(pack.nodes); - value.add(pack.leaf_nodes); - value.add(pack.object_node); - value.add(pack.tri_woop); - value.add(pack.prim_type); - value.add(pack.prim_visibility); - value.add(pack.prim_index); - value.add(pack.prim_object); - - Cache::global.insert(key, value); - - cache_filename = key.get_filename(); -} - -void BVH::clear_cache_except() -{ - set<string> except; - - if(!cache_filename.empty()) - except.insert(cache_filename); - - foreach(Object *ob, objects) { - Mesh *mesh = ob->mesh; - BVH *bvh = mesh->bvh; - - if(bvh && !bvh->cache_filename.empty()) - except.insert(bvh->cache_filename); - } - - Cache::global.clear_except("bvh", except); -} - /* Building */ void BVH::build(Progress& progress) { progress.set_substatus("Building BVH"); - /* cache read */ - CacheData key("bvh"); - - if(params.use_cache) { - progress.set_substatus("Looking in BVH cache"); - - if(cache_read(key)) - return; - } - /* build nodes */ BVHBuild bvh_build(objects, pack.prim_type, @@ -227,18 +113,6 @@ void BVH::build(Progress& progress) /* free build nodes */ root->deleteSubtree(); - - if(progress.get_cancel()) return; - - /* cache write */ - if(params.use_cache) { - progress.set_substatus("Writing BVH cache"); - cache_write(key); - - /* clear other bvh files from cache */ - if(params.top_level) - clear_cache_except(); - } } /* Refitting */ diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h index 669d2ccdcd5..272a3fa1514 100644 --- a/intern/cycles/bvh/bvh.h +++ b/intern/cycles/bvh/bvh.h @@ -20,7 +20,6 @@ #include "bvh_params.h" -#include "util_string.h" #include "util_types.h" #include "util_vector.h" @@ -30,7 +29,6 @@ class BVHNode; struct BVHStackEntry; class BVHParams; class BoundBox; -class CacheData; class LeafNode; class Object; class Progress; @@ -87,7 +85,6 @@ public: PackedBVH pack; BVHParams params; vector<Object*> objects; - string cache_filename; static BVH *create(const BVHParams& params, const vector<Object*>& objects); virtual ~BVH() {} @@ -95,15 +92,9 @@ public: void build(Progress& progress); void refit(Progress& progress); - void clear_cache_except(); - protected: BVH(const BVHParams& params, const vector<Object*>& objects); - /* cache */ - bool cache_read(CacheData& key); - void cache_write(CacheData& key); - /* triangles and strands*/ void pack_primitives(); void pack_triangle(int idx, float4 woop[3]); diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp index db96490a36f..8745e39c21e 100644 --- a/intern/cycles/bvh/bvh_binning.cpp +++ b/intern/cycles/bvh/bvh_binning.cpp @@ -76,8 +76,8 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims) prefetch_L2(&prims[start() + i + 8]); /* map even and odd primitive to bin */ - BVHReference prim0 = prims[start() + i + 0]; - BVHReference prim1 = prims[start() + i + 1]; + const BVHReference& prim0 = prims[start() + i + 0]; + const BVHReference& prim1 = prims[start() + i + 1]; int4 bin0 = get_bin(prim0.bounds()); int4 bin1 = get_bin(prim1.bounds()); @@ -96,7 +96,7 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims) /* for uneven number of primitives */ if(i < ssize_t(size())) { /* map primitive to bin */ - BVHReference prim0 = prims[start() + i]; + const BVHReference& prim0 = prims[start() + i]; int4 bin0 = get_bin(prim0.bounds()); /* increase bounds of bins */ diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index a44ad656316..45b0aaa2d63 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -234,8 +234,14 @@ BVHNode* BVHBuild::run() return NULL; /* init spatial splits */ - if(params.top_level) /* todo: get rid of this */ + if(params.top_level) { + /* NOTE: Technically it is supported by the builder but it's not really + * optimized for speed yet and not really clear yet if it has measurable + * improvement on render time. Needs some extra investigation before + * enabling spatial split for top level BVH. + */ params.use_spatial_split = false; + } spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha; spatial_right_bounds.clear(); @@ -276,6 +282,8 @@ BVHNode* BVHBuild::run() else if(!params.use_spatial_split) { /*rotate(rootnode, 4, 5);*/ rootnode->update_visibility(); + } + if(rootnode != NULL) { VLOG(1) << "BVH build statistics:\n" << " Build time: " << time_dt() - build_start_time << "\n" << " Total number of nodes: " @@ -525,11 +533,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range) /* Extend an array when needed. */ if(prim_type.size() < range.end()) { assert(params.use_spatial_split); - /* TODO(sergey): We might want to look into different policies of - * re-allocation here, so on the one hand we would not do as much - * re-allocations and on the other hand will have small memory - * overhead. - */ + prim_type.reserve(references.size()); + prim_index.reserve(references.size()); + prim_object.reserve(references.size()); prim_type.resize(range.end()); prim_index.resize(range.end()); prim_object.resize(range.end()); diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h index af8d8eeb3ee..faa995c3f29 100644 --- a/intern/cycles/bvh/bvh_params.h +++ b/intern/cycles/bvh/bvh_params.h @@ -43,9 +43,6 @@ public: /* object or mesh level bvh */ bool top_level; - /* disk cache */ - bool use_cache; - /* QBVH */ bool use_qbvh; @@ -71,7 +68,6 @@ public: max_curve_leaf_size = 2; top_level = false; - use_cache = false; use_qbvh = false; } diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index 2290c4143ad..534c1aa73b5 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -191,11 +191,16 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, } } - /* duplicate or unsplit references intersecting both sides. */ + /* Duplicate or unsplit references intersecting both sides. + * + * Duplication happens into a temporary pre-allocated vector in order to + * reduce number of memmove() calls happening in vector.insert(). + */ + vector<BVHReference> new_refs; + new_refs.reserve(right_start - left_end); while(left_end < right_start) { /* split reference. */ BVHReference lref, rref; - split_reference(builder, lref, rref, refs[left_end], this->dim, this->pos); /* compute SAH for duplicate/unsplit candidates. */ @@ -234,61 +239,36 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, left_bounds = ldb; right_bounds = rdb; refs[left_end++] = lref; - refs.insert(refs.begin() + right_end, rref); + new_refs.push_back(rref); right_end++; } } - + /* Insert duplicated references into actual array in one go. */ + if(new_refs.size() != 0) { + refs.insert(refs.begin() + right_end - new_refs.size(), + new_refs.begin(), + new_refs.end()); + } left = BVHRange(left_bounds, left_start, left_end - left_start); right = BVHRange(right_bounds, right_start, right_end - right_start); } -void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos) +void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, + const Transform *tfm, + int prim_index, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) { - /* initialize boundboxes */ - BoundBox left_bounds = BoundBox::empty; - BoundBox right_bounds = BoundBox::empty; - - /* loop over vertices/edges. */ - Object *ob = builder->objects[ref.prim_object()]; - const Mesh *mesh = ob->mesh; - - if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { - const int *inds = mesh->triangles[ref.prim_index()].v; - const float3 *verts = &mesh->verts[0]; - const float3* v1 = &verts[inds[2]]; - - for(int i = 0; i < 3; i++) { - const float3* v0 = v1; - int vindex = inds[i]; - v1 = &verts[vindex]; - float v0p = (*v0)[dim]; - float v1p = (*v1)[dim]; - - /* insert vertex to the boxes it belongs to. */ - if(v0p <= pos) - left_bounds.grow(*v0); - - if(v0p >= pos) - right_bounds.grow(*v0); - - /* edge intersects the plane => insert intersection to both boxes. */ - if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { - float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); - left_bounds.grow(t); - right_bounds.grow(t); - } - } - } - else { - /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ - const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()); - const int k1 = k0 + 1; - const float4 key0 = mesh->curve_keys[k0]; - const float4 key1 = mesh->curve_keys[k1]; - const float3 v0 = float4_to_float3(key0); - const float3 v1 = float4_to_float3(key1); - + const int *inds = mesh->triangles[prim_index].v; + const float3 *verts = &mesh->verts[0]; + float3 v1 = tfm ? transform_point(tfm, verts[inds[2]]) : verts[inds[2]]; + + for(int i = 0; i < 3; i++) { + float3 v0 = v1; + int vindex = inds[i]; + v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex]; float v0p = v0[dim]; float v1p = v1[dim]; @@ -299,12 +279,6 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH if(v0p >= pos) right_bounds.grow(v0); - if(v1p <= pos) - left_bounds.grow(v1); - - if(v1p >= pos) - right_bounds.grow(v1); - /* edge intersects the plane => insert intersection to both boxes. */ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); @@ -312,6 +286,159 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH right_bounds.grow(t); } } +} + +void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, + const Transform *tfm, + int prim_index, + int segment_index, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ + const int k0 = mesh->curves[prim_index].first_key + segment_index; + const int k1 = k0 + 1; + const float4& key0 = mesh->curve_keys[k0]; + const float4& key1 = mesh->curve_keys[k1]; + float3 v0 = float4_to_float3(key0); + float3 v1 = float4_to_float3(key1); + + if(tfm != NULL) { + v0 = transform_point(tfm, v0); + v1 = transform_point(tfm, v1); + } + + float v0p = v0[dim]; + float v1p = v1[dim]; + + /* insert vertex to the boxes it belongs to. */ + if(v0p <= pos) + left_bounds.grow(v0); + + if(v0p >= pos) + right_bounds.grow(v0); + + if(v1p <= pos) + left_bounds.grow(v1); + + if(v1p >= pos) + right_bounds.grow(v1); + + /* edge intersects the plane => insert intersection to both boxes. */ + if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { + float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); + left_bounds.grow(t); + right_bounds.grow(t); + } +} + +void BVHSpatialSplit::split_triangle_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + split_triangle_primitive(mesh, + NULL, + ref.prim_index(), + dim, + pos, + left_bounds, + right_bounds); +} + +void BVHSpatialSplit::split_curve_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + split_curve_primitive(mesh, + NULL, + ref.prim_index(), + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()), + dim, + pos, + left_bounds, + right_bounds); +} + +void BVHSpatialSplit::split_object_reference(const Object *object, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + Mesh *mesh = object->mesh; + for(int tri_idx = 0; tri_idx < mesh->triangles.size(); ++tri_idx) { + split_triangle_primitive(mesh, + &object->tfm, + tri_idx, + dim, + pos, + left_bounds, + right_bounds); + } + for(int curve_idx = 0; curve_idx < mesh->curves.size(); ++curve_idx) { + Mesh::Curve &curve = mesh->curves[curve_idx]; + for(int segment_idx = 0; + segment_idx < curve.num_keys - 1; + ++segment_idx) + { + split_curve_primitive(mesh, + &object->tfm, + curve_idx, + segment_idx, + dim, + pos, + left_bounds, + right_bounds); + } + } +} + +void BVHSpatialSplit::split_reference(BVHBuild *builder, + BVHReference& left, + BVHReference& right, + const BVHReference& ref, + int dim, + float pos) +{ + /* initialize boundboxes */ + BoundBox left_bounds = BoundBox::empty; + BoundBox right_bounds = BoundBox::empty; + + /* loop over vertices/edges. */ + Object *ob = builder->objects[ref.prim_object()]; + const Mesh *mesh = ob->mesh; + + if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { + split_triangle_reference(ref, + mesh, + dim, + pos, + left_bounds, + right_bounds); + } + else if(ref.prim_type() & PRIMITIVE_ALL_CURVE) { + split_curve_reference(ref, + mesh, + dim, + pos, + left_bounds, + right_bounds); + } + else { + split_object_reference(ob, + dim, + pos, + left_bounds, + right_bounds); + } /* intersect with original bounds. */ left_bounds.max[dim] = pos; diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h index 5b739311e5f..1e46bb66203 100644 --- a/intern/cycles/bvh/bvh_split.h +++ b/intern/cycles/bvh/bvh_split.h @@ -55,7 +55,58 @@ public: BVHSpatialSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH); void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range); - void split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos); + void split_reference(BVHBuild *builder, + BVHReference& left, + BVHReference& right, + const BVHReference& ref, + int dim, + float pos); + +protected: + /* Lower-level functions which calculates boundaries of left and right nodes + * needed for spatial split. + * + * Operates directly with primitive specified by it's index, reused by higher + * level splitting functions. + */ + void split_triangle_primitive(const Mesh *mesh, + const Transform *tfm, + int prim_index, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + void split_curve_primitive(const Mesh *mesh, + const Transform *tfm, + int prim_index, + int segment_index, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + + /* Lower-level functions which calculates boundaries of left and right nodes + * needed for spatial split. + * + * Operates with BVHReference, internally uses lower level API functions. + */ + void split_triangle_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + void split_curve_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + void split_object_reference(const Object *object, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); }; /* Mixed Object-Spatial Split */ diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake index d7c59f42a5e..10a166b6e44 100644 --- a/intern/cycles/cmake/external_libs.cmake +++ b/intern/cycles/cmake/external_libs.cmake @@ -87,6 +87,13 @@ if(CYCLES_STANDALONE_REPOSITORY) find_package(OpenEXR) #### + # OpenShadingLanguage + if(WITH_CYCLES_OSL) + find_package(OpenShadingLanguage REQUIRED) + find_package(LLVM REQUIRED) + endif() + + #### # Boost set(__boost_packages filesystem regex system thread date_time) if(WITH_CYCLES_NETWORK) @@ -97,6 +104,8 @@ if(CYCLES_STANDALONE_REPOSITORY) # libraries works, could be different for someone's else libs.. if(APPLE OR MSVC) list(APPEND __boost_packages wave) + elseif(NOT (${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6")) + list(APPEND __boost_packages wave) endif() endif() find_package(Boost 1.48 COMPONENTS ${__boost_packages} REQUIRED) @@ -114,13 +123,6 @@ if(CYCLES_STANDALONE_REPOSITORY) set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB") #### - # OpenShadingLanguage - if(WITH_CYCLES_OSL) - find_package(OpenShadingLanguage REQUIRED) - find_package(LLVM REQUIRED) - endif() - - #### # Logging if(WITH_CYCLES_LOGGING) find_package(Glog REQUIRED) diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h index ba79f8c88ae..8c32d03135e 100644 --- a/intern/cycles/device/device_memory.h +++ b/intern/cycles/device/device_memory.h @@ -211,7 +211,10 @@ public: T *resize(size_t width, size_t height = 0, size_t depth = 0) { data_size = width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth); - data.resize(data_size); + if(data.resize(data_size) == NULL) { + clear(); + return NULL; + } data_width = width; data_height = height; data_depth = depth; @@ -226,7 +229,9 @@ public: T *copy(T *ptr, size_t width, size_t height = 0, size_t depth = 0) { T *mem = resize(width, height, depth); - memcpy(mem, ptr, memory_size()); + if(mem != NULL) { + memcpy(mem, ptr, memory_size()); + } return mem; } diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp index d1f941ad9f2..afa35224aba 100644 --- a/intern/cycles/device/device_network.cpp +++ b/intern/cycles/device/device_network.cpp @@ -574,13 +574,13 @@ protected: network_device_memory mem; string name; InterpolationType interpolation; - ExtensionType extension_typr; + ExtensionType extension_type; device_ptr client_pointer; rcv.read(name); rcv.read(mem); rcv.read(interpolation); - rcv.read(extension); + rcv.read(extension_type); lock.unlock(); client_pointer = mem.device_pointer; @@ -596,7 +596,7 @@ protected: rcv.read_buffer((uint8_t*)mem.data_pointer, data_size); - device->tex_alloc(name.c_str(), mem, interpolation, extension); + device->tex_alloc(name.c_str(), mem, interpolation, extension_type); pointer_mapping_insert(client_pointer, mem.device_pointer); } diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index fee9a8a803d..7f16a73d966 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -313,7 +313,7 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) continue; } if(!opencl_device_version_check(device_id)) { - FIRST_VLOG(2) << "Ignoting device " << device_name + FIRST_VLOG(2) << "Ignoring device " << device_name << " due to old compiler version."; continue; } @@ -327,8 +327,8 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) &device_type, NULL) != CL_SUCCESS) { - FIRST_VLOG(2) << "Ignoting device " << device_name - << ", faield to fetch device type."; + FIRST_VLOG(2) << "Ignoring device " << device_name + << ", failed to fetch device type."; continue; } FIRST_VLOG(2) << "Adding new device " << device_name << "."; @@ -339,7 +339,7 @@ void opencl_get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices) device_name)); } else { - FIRST_VLOG(2) << "Ignoting device " << device_name + FIRST_VLOG(2) << "Ignoring device " << device_name << ", not officially supported yet."; } } @@ -581,7 +581,7 @@ public: ProgramName program_name, thread_scoped_lock& slot_locker) { - switch (program_name) { + switch(program_name) { case OCL_DEV_BASE_PROGRAM: store_something<cl_program>(platform, device, @@ -995,6 +995,7 @@ public: VLOG(2) << "Loaded kernel from " << clbin << "."; } else { + VLOG(2) << "Kernel file " << clbin << " either doesn't exist or failed to be loaded by driver."; string init_kernel_source = "#include \"kernels/opencl/kernel.cl\" // " + kernel_md5 + "\n"; /* If does not exist or loading binary failed, compile kernel. */ @@ -1605,7 +1606,7 @@ protected: * mega kernel is not getting feature-based optimizations. * * Ideally we need always compile kernel with as less features - * enabed as possible to keep performance at it's max. + * enabled as possible to keep performance at it's max. */ return ""; } @@ -3689,7 +3690,7 @@ string device_opencl_capabilities(void) APPEND_STRING_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what) vector<cl_device_id> device_ids; - for (cl_uint platform = 0; platform < num_platforms; ++platform) { + for(cl_uint platform = 0; platform < num_platforms; ++platform) { cl_platform_id platform_id = platform_ids[platform]; result += string_printf("Platform #%u\n", platform); @@ -3714,7 +3715,7 @@ string device_opencl_capabilities(void) num_devices, &device_ids[0], NULL)); - for (cl_uint device = 0; device < num_devices; ++device) { + for(cl_uint device = 0; device < num_devices; ++device) { cl_device_id device_id = device_ids[device]; result += string_printf("\t\tDevice: #%u\n", device); diff --git a/intern/cycles/kernel/geom/geom_bvh_shadow.h b/intern/cycles/kernel/geom/geom_bvh_shadow.h index e4cba99dc96..cb3f75f2a8f 100644 --- a/intern/cycles/kernel/geom/geom_bvh_shadow.h +++ b/intern/cycles/kernel/geom/geom_bvh_shadow.h @@ -59,7 +59,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float isect_t = tmax; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if BVH_FEATURE(BVH_INSTANCING) @@ -302,7 +302,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -338,7 +338,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -353,7 +353,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h index a73139f9c88..a093b9b55aa 100644 --- a/intern/cycles/kernel/geom/geom_bvh_subsurface.h +++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h @@ -63,7 +63,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, uint num_hits = 0; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if defined(__KERNEL_SSE2__) @@ -240,7 +240,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = subsurface_object; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -278,7 +278,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h index 73d79fd78ee..13d118b6d19 100644 --- a/intern/cycles/kernel/geom/geom_bvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h @@ -65,7 +65,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, int object = OBJECT_NONE; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif isect->t = ray->t; @@ -342,7 +342,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -378,7 +378,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_volume.h b/intern/cycles/kernel/geom/geom_bvh_volume.h index 41c784869f2..656cd6e7a0e 100644 --- a/intern/cycles/kernel/geom/geom_bvh_volume.h +++ b/intern/cycles/kernel/geom/geom_bvh_volume.h @@ -59,7 +59,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif isect->t = ray->t; @@ -267,7 +267,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -307,7 +307,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_volume_all.h b/intern/cycles/kernel/geom/geom_bvh_volume_all.h index b6db36f4b17..8f7e3adae51 100644 --- a/intern/cycles/kernel/geom/geom_bvh_volume_all.h +++ b/intern/cycles/kernel/geom/geom_bvh_volume_all.h @@ -62,7 +62,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if BVH_FEATURE(BVH_INSTANCING) @@ -230,10 +230,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); #else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -268,10 +268,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -311,10 +311,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -341,7 +341,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -384,7 +384,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits_in_instance) { float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -397,7 +397,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, else { float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index 9d0a008fff1..ffd2f3b778f 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -428,8 +428,8 @@ ccl_device_inline void qbvh_instance_push(KernelGlobals *kg, ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t) { if(*t != FLT_MAX) { - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - *t *= len(transform_direction(&tfm, 1.0f/(*idir))); + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + *t /= len(transform_direction(&tfm, ray->D)); } *P = ray->P; @@ -441,8 +441,8 @@ ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac) { - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - *t_fac = len(transform_direction(&tfm, 1.0f/(*idir))); + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + *t_fac = 1.0f / len(transform_direction(&tfm, ray->D)); *P = ray->P; *dir = bvh_clamp_direction(ray->D); @@ -453,15 +453,21 @@ ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, co #ifdef __OBJECT_MOTION__ /* Transform ray into object space to enter motion blurred object in BVH */ -ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t, Transform *tfm) +ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + ccl_addr_space float *t, + Transform *itfm) { - Transform itfm; - *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); + object_fetch_transform_motion_test(kg, object, ray->time, itfm); - *P = transform_point(&itfm, ray->P); + *P = transform_point(itfm, ray->P); float len; - *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len)); + *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); if(*t != FLT_MAX) @@ -475,18 +481,24 @@ ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, c * TODO(sergey): Investigate if passing NULL instead of t1 gets optimized * so we can avoid having this duplication. */ -ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, float *t1, Transform *tfm) +ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float *t, + float *t1, + Transform *itfm) { - Transform itfm; - *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); + object_fetch_transform_motion_test(kg, object, ray->time, itfm); - *P = transform_point(&itfm, ray->P); + *P = transform_point(itfm, ray->P); float len; - *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len)); + *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); - if(*t != FLT_MAX) *t *= len; @@ -497,10 +509,18 @@ ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, /* Transorm ray to exit motion blurred object in BVH */ -ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t, Transform *tfm) +ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + ccl_addr_space float *t, + Transform *itfm) { - if(*t != FLT_MAX) - *t *= len(transform_direction(tfm, 1.0f/(*idir))); + if(*t != FLT_MAX) { + *t /= len(transform_direction(itfm, ray->D)); + } *P = ray->P; *dir = bvh_clamp_direction(ray->D); @@ -509,10 +529,16 @@ ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, co /* Same as above, but returns scale factor to apply to multiple intersection distances */ -ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac, Transform *tfm) +ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float *t_fac, + Transform *itfm) { - *t_fac = len(transform_direction(tfm, 1.0f/(*idir))); - + *t_fac /= len(transform_direction(itfm, ray->D)); *P = ray->P; *dir = bvh_clamp_direction(ray->D); *idir = bvh_inverse_direction(*dir); diff --git a/intern/cycles/kernel/geom/geom_qbvh_shadow.h b/intern/cycles/kernel/geom/geom_qbvh_shadow.h index dc37e6ecfa4..4564d5baf5e 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_shadow.h +++ b/intern/cycles/kernel/geom/geom_qbvh_shadow.h @@ -55,7 +55,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float isect_t = tmax; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif *num_hits = 0; @@ -317,7 +317,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -357,7 +357,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -370,7 +370,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h index d85e1a4691e..fe231720cf7 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h +++ b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h @@ -58,7 +58,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, uint num_hits = 0; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -256,7 +256,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = subsurface_object; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -297,7 +297,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_traversal.h b/intern/cycles/kernel/geom/geom_qbvh_traversal.h index 7e356ea062b..4e1678665c0 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_qbvh_traversal.h @@ -63,7 +63,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, int object = OBJECT_NONE; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -356,7 +356,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_tfm); + qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_itfm); #else qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist); #endif @@ -395,7 +395,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume.h b/intern/cycles/kernel/geom/geom_qbvh_volume.h index d8cfa3a4061..40864471d13 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_volume.h +++ b/intern/cycles/kernel/geom/geom_qbvh_volume.h @@ -54,7 +54,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -281,7 +281,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -322,7 +322,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume_all.h b/intern/cycles/kernel/geom/geom_qbvh_volume_all.h index 056ca9a1ad9..75e4c4e8d96 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_volume_all.h +++ b/intern/cycles/kernel/geom/geom_qbvh_volume_all.h @@ -57,7 +57,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif uint num_hits = 0; @@ -247,10 +247,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); #else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -285,10 +285,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -328,10 +328,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -355,7 +355,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -400,7 +400,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits_in_instance) { float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -413,7 +413,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, else { float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h index 3ef918dc842..ba309a1dc53 100644 --- a/intern/cycles/kernel/geom/geom_triangle_intersect.h +++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h @@ -98,7 +98,7 @@ void triangle_intersect_precalc(float3 dir, } /* TODO(sergey): Make it general utility function. */ -ccl_device_inline float xor_signmast(float x, int y) +ccl_device_inline float xor_signmask(float x, int y) { return __int_as_float(__float_as_int(x) ^ y); } @@ -140,13 +140,15 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, /* Calculate scaled barycentric coordinates. */ float U = Cx * By - Cy * Bx; - int sign_mask = (__float_as_int(U) & 0x80000000); float V = Ax * Cy - Ay * Cx; - if(sign_mask != (__float_as_int(V) & 0x80000000)) { - return false; - } float W = Bx * Ay - By * Ax; - if(sign_mask != (__float_as_int(W) & 0x80000000)) { + const int sign_mask = (__float_as_int(U) & 0x80000000); + /* TODO(sergey): Check if multiplication plus sign check is faster + * or at least same speed (but robust for endian types). + */ + if(sign_mask != (__float_as_int(V) & 0x80000000) || + sign_mask != (__float_as_int(W) & 0x80000000)) + { return false; } @@ -156,13 +158,13 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, return false; } - /* Calculate scaled z−coordinates of vertices and use them to calculate + /* Calculate scaled z-coordinates of vertices and use them to calculate * the hit distance. */ const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz; - const float sign_T = xor_signmast(T, sign_mask); + const float sign_T = xor_signmask(T, sign_mask); if((sign_T < 0.0f) || - (sign_T > isect->t * xor_signmast(det, sign_mask))) + (sign_T > isect->t * xor_signmask(det, sign_mask))) { return false; } @@ -173,6 +175,16 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg, if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility) #endif { +#ifdef __KERNEL_GPU__ + float4 a = tri_b - tri_a, b = tri_c - tri_a; + if(len_squared(make_float3(a.y*b.z - a.z*b.y, + a.z*b.x - a.x*b.z, + a.x*b.y - a.y*b.x)) == 0.0f) + { + return false; + } +#endif + /* Normalize U, V, W, and T. */ const float inv_det = 1.0f / det; isect->prim = triAddr; @@ -253,9 +265,9 @@ ccl_device_inline void triangle_intersect_subsurface( * the hit distance. */ const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz; - const float sign_T = xor_signmast(T, sign_mask); + const float sign_T = xor_signmask(T, sign_mask); if((sign_T < 0.0f) || - (sign_T > tmax * xor_signmast(det, sign_mask))) + (sign_T > tmax * xor_signmask(det, sign_mask))) { return; } diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index 2fca83c615f..0cb56461f29 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -31,6 +31,13 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian float3 throughput = make_float3(1.0f, 1.0f, 1.0f); bool is_sss_sample = is_sss; + ray.P = sd->P + sd->Ng; + ray.D = -sd->Ng; + ray.t = FLT_MAX; +#ifdef __CAMERA_MOTION__ + ray.time = TIME_INVALID; +#endif + /* init radiance */ path_radiance_init(&L_sample, kernel_data.film.use_light_pass); @@ -143,7 +150,7 @@ ccl_device bool is_aa_pass(ShaderEvalType type) ccl_device bool is_light_pass(ShaderEvalType type) { - switch (type) { + switch(type) { case SHADER_EVAL_AO: case SHADER_EVAL_COMBINED: case SHADER_EVAL_SHADOW: @@ -255,7 +262,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, sample); } - switch (type) { + switch(type) { /* data passes */ case SHADER_EVAL_NORMAL: { diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 67651f96544..8d439ceb0d7 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -267,11 +267,14 @@ ccl_device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float /* ray differential */ ray->dP = differential3_zero(); + Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f)); + float3 Ddiff = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))); + Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f)); - ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D; + ray->dD.dx = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff; Pcamera = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f)); - ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - ray->D; + ray->dD.dy = normalize(transform_direction(&cameratoworld, panorama_to_direction(kg, Pcamera.x, Pcamera.y))) - Ddiff; #endif } diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h index d02670f630a..04c4cf35587 100644 --- a/intern/cycles/kernel/kernel_compat_cpu.h +++ b/intern/cycles/kernel/kernel_compat_cpu.h @@ -144,7 +144,7 @@ template<typename T> struct texture_image { iy = wrap_periodic(iy, height); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ @@ -168,16 +168,16 @@ template<typename T> struct texture_image { niy = wrap_periodic(iy+1, height); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ case EXTENSION_EXTEND: - ix = wrap_clamp(ix, width); - iy = wrap_clamp(iy, height); - nix = wrap_clamp(ix+1, width); niy = wrap_clamp(iy+1, height); + + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); break; } @@ -190,8 +190,8 @@ template<typename T> struct texture_image { } else { /* Bicubic b-spline interpolation. */ - const float tx = frac(x*(float)width - 0.5f, &ix); - const float ty = frac(y*(float)height - 0.5f, &iy); + float tx = frac(x*(float)width - 0.5f, &ix); + float ty = frac(y*(float)height - 0.5f, &iy); int pix, piy, nnix, nniy; switch(extension) { case EXTENSION_REPEAT: @@ -208,14 +208,11 @@ template<typename T> struct texture_image { nniy = wrap_periodic(iy+2, height); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || x > 1.0f || y > 1.0f) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ case EXTENSION_EXTEND: - ix = wrap_clamp(ix, width); - iy = wrap_clamp(iy, height); - pix = wrap_clamp(ix-1, width); piy = wrap_clamp(iy-1, height); @@ -224,6 +221,9 @@ template<typename T> struct texture_image { nnix = wrap_clamp(ix+2, width); nniy = wrap_clamp(iy+2, height); + + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); break; } @@ -279,7 +279,9 @@ template<typename T> struct texture_image { iz = wrap_periodic(iz, depth); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || z < 0.0f || + x > 1.0f || y > 1.0f || z > 1.0f) + { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ @@ -308,18 +310,20 @@ template<typename T> struct texture_image { niz = wrap_periodic(iz+1, depth); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || z < 0.0f || + x > 1.0f || y > 1.0f || z > 1.0f) + { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ case EXTENSION_EXTEND: - ix = wrap_clamp(ix, width); - iy = wrap_clamp(iy, height); - iz = wrap_clamp(iz, depth); - nix = wrap_clamp(ix+1, width); niy = wrap_clamp(iy+1, height); niz = wrap_clamp(iz+1, depth); + + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); + iz = wrap_clamp(iz, depth); break; } @@ -363,15 +367,13 @@ template<typename T> struct texture_image { nniz = wrap_periodic(iz+2, depth); break; case EXTENSION_CLIP: - if (x < 0.0f || y < 0.0f || x >= width || y >= height) { + if(x < 0.0f || y < 0.0f || z < 0.0f || + x > 1.0f || y > 1.0f || z > 1.0f) + { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } /* Fall through. */ case EXTENSION_EXTEND: - ix = wrap_clamp(ix, width); - iy = wrap_clamp(iy, height); - iz = wrap_clamp(iz, depth); - pix = wrap_clamp(ix-1, width); piy = wrap_clamp(iy-1, height); piz = wrap_clamp(iz-1, depth); @@ -383,6 +385,10 @@ template<typename T> struct texture_image { nnix = wrap_clamp(ix+2, width); nniy = wrap_clamp(iy+2, height); nniz = wrap_clamp(iz+2, depth); + + ix = wrap_clamp(ix, width); + iy = wrap_clamp(iy, height); + iz = wrap_clamp(iz, depth); break; } diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index eb2d39d5020..7590ec2d706 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -620,7 +620,7 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp, } } -#if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86)) +#if defined(__KERNEL_CUDA__) && (__CUDA_ARCH__ >= 500) && (defined(i386) || defined(_M_IX86)) ccl_device_noinline #else ccl_device diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index fe85a6b6e4b..4485be8a5b3 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -150,7 +150,7 @@ ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg, RNG *rng, /* setup ray */ ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng)); - ray->D = bsdf_omega_in; + ray->D = normalize(bsdf_omega_in); ray->t = FLT_MAX; #ifdef __RAY_DIFFERENTIALS__ ray->dP = ccl_fetch(sd, dP); @@ -257,7 +257,7 @@ ccl_device_inline bool kernel_path_surface_bounce(KernelGlobals *kg, ccl_addr_sp /* setup ray */ ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng)); - ray->D = bsdf_omega_in; + ray->D = normalize(bsdf_omega_in); if(state->bounce == 0) ray->t -= ccl_fetch(sd, ray_length); /* clipping works through transparent */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index acd2f5d0673..740a5f1f5d3 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1036,7 +1036,7 @@ enum QueueNumber { * contribution for AO are enqueued here. */ QUEUE_SHADOW_RAY_CAST_DL_RAYS = 3, /* All rays for which a shadow ray should be cast to determine radiance - * contributuin for direct lighting are enqueued here. + * contributing for direct lighting are enqueued here. */ }; diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index 27c0b44a80d..0a74a9deba9 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -374,7 +374,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba /* distance sampling */ sample_t = kernel_volume_distance_sample(ray->t, sigma_t, channel, xi, &transmittance, &pdf); - /* modifiy pdf for hit/miss decision */ + /* modify pdf for hit/miss decision */ if(probalistic_scatter) pdf *= make_float3(1.0f, 1.0f, 1.0f) - volume_color_transmittance(sigma_t, t); @@ -422,7 +422,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(KernelGloba /* heterogeneous volume distance sampling: integrate stepping through the * volume until we reach the end, get absorbed entirely, or run out of - * iterations. this does probalistically scatter or get transmitted through + * iterations. this does probabilistically scatter or get transmitted through * for path tracing where we don't want to branch. */ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd, PathRadiance *L, float3 *throughput, RNG *rng) @@ -610,7 +610,7 @@ typedef struct VolumeSegment { /* record volume steps to the end of the volume. * * it would be nice if we could only record up to the point that we need to scatter, - * but the entire segment is needed to do always scattering, rather than probalistically + * but the entire segment is needed to do always scattering, rather than probabilistically * hitting or missing the volume. if we don't know the transmittance at the end of the * volume we can't generate stratified distance samples up to that transmittance */ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *state, @@ -766,7 +766,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( sd->randb_closure = rphase*3.0f - channel; float xi = rscatter; - /* probalistic scattering decision based on transmittance */ + /* probabilistic scattering decision based on transmittance */ if(probalistic_scatter) { float sample_transmittance = kernel_volume_channel_get(segment->accum_transmittance, channel); @@ -846,7 +846,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( float3 distance_pdf; sample_t = prev_t + kernel_volume_distance_sample(step_t, step->sigma_t, channel, xi, &transmittance, &distance_pdf); - /* modifiy pdf for hit/miss decision */ + /* modify pdf for hit/miss decision */ if(probalistic_scatter) distance_pdf *= make_float3(1.0f, 1.0f, 1.0f) - segment->accum_transmittance; @@ -942,7 +942,7 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter( /* decide if we need to use decoupled or not */ ccl_device bool kernel_volume_use_decoupled(KernelGlobals *kg, bool heterogeneous, bool direct, int sampling_method) { - /* decoupled ray marching for heterogenous volumes not supported on the GPU, + /* decoupled ray marching for heterogeneous volumes not supported on the GPU, * which also means equiangular and multiple importance sampling is not * support for that case */ #ifdef __KERNEL_GPU__ diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp index 2facced0914..4d70bc80006 100644 --- a/intern/cycles/kernel/osl/background.cpp +++ b/intern/cycles/kernel/osl/background.cpp @@ -77,7 +77,7 @@ public: ClosureParam *closure_background_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"), CLOSURE_FINISH_PARAM(GenericBackgroundClosure) }; return params; @@ -98,7 +98,7 @@ CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure) ClosureParam *closure_ambient_occlusion_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(AmbientOcclusionClosure, label, "label"), CLOSURE_FINISH_PARAM(AmbientOcclusionClosure) }; return params; diff --git a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp index 43929fbe928..b3c71e4a706 100644 --- a/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_diffuse_ramp.cpp @@ -93,7 +93,7 @@ ClosureParam *closure_bsdf_diffuse_ramp_params() static ClosureParam params[] = { CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, sc.N), CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"), CLOSURE_FINISH_PARAM(DiffuseRampClosure) }; return params; diff --git a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp index 497c4f0dc5c..99f510d31ed 100644 --- a/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp +++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp @@ -93,7 +93,7 @@ ClosureParam *closure_bsdf_phong_ramp_params() CLOSURE_FLOAT3_PARAM(PhongRampClosure, sc.N), CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0), CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"), CLOSURE_FINISH_PARAM(PhongRampClosure) }; return params; diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp index 02935542c56..9a95fa57a81 100644 --- a/intern/cycles/kernel/osl/emissive.cpp +++ b/intern/cycles/kernel/osl/emissive.cpp @@ -77,7 +77,7 @@ public: ClosureParam *closure_emission_params() { static ClosureParam params[] = { - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"), CLOSURE_FINISH_PARAM(GenericEmissiveClosure) }; return params; diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 88998037751..bc395922077 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -69,7 +69,7 @@ ClosureParam *closure_bssrdf_cubic_params() CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, radius), CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.data1), CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.T.x), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(CubicBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(CubicBSSRDFClosure) }; return params; @@ -97,7 +97,7 @@ ClosureParam *closure_bssrdf_gaussian_params() CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, sc.N), CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, radius), CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, sc.data1), - CLOSURE_STRING_KEYPARAM("label"), + CLOSURE_STRING_KEYPARAM(GaussianBSSRDFClosure, label, "label"), CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure) }; return params; diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index ef67ef52fc0..c0bf25ac1c7 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -72,12 +72,17 @@ void name(RendererServices *, int id, void *data) \ #define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname) #define CLOSURE_FLOAT3_PARAM(st, fld) \ - { TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) } + { TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) } #define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z) #define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z) #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2]) +#if OSL_LIBRARY_VERSION_CODE < 10700 +# undef CLOSURE_STRING_KEYPARAM +# define CLOSURE_STRING_KEYPARAM(st, fld, key) { TypeDesc::TypeString, 0, key, 0 } +#endif + /* Closure */ class CClosurePrimitive { @@ -97,6 +102,10 @@ public: virtual void setup() {} Category category; + +#if OSL_LIBRARY_VERSION_CODE >= 10700 + OSL::ustring label; +#endif }; /* BSDF */ @@ -175,7 +184,7 @@ static ClosureParam *bsdf_##lower##_params() \ /* parameters */ #define BSDF_CLOSURE_CLASS_END(Upper, lower) \ - CLOSURE_STRING_KEYPARAM("label"), \ + CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \ CLOSURE_FINISH_PARAM(Upper##Closure) \ }; \ return params; \ @@ -223,7 +232,7 @@ static ClosureParam *volume_##lower##_params() \ /* parameters */ #define VOLUME_CLOSURE_CLASS_END(Upper, lower) \ - CLOSURE_STRING_KEYPARAM("label"), \ + CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), \ CLOSURE_FINISH_PARAM(Upper##Closure) \ }; \ return params; \ diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 190234a7706..aa2befd6e98 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -104,6 +104,55 @@ public: const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy, const OSL::Vec3 &dPdz, int nchannels, float *result); +#if OSL_LIBRARY_VERSION_CODE >= 10600 + bool texture(ustring filename, + TextureHandle * /*texture_handle*/, + TexturePerthread * /*texture_thread_info*/, + TextureOpt &options, + OSL::ShaderGlobals *sg, + float s, float t, + float dsdx, float dtdx, float dsdy, float dtdy, + int nchannels, + float *result, + float * /*dresultds*/, + float * /*dresultdt*/) + { + /* TODO(sergey): Support derivatives. */ + return texture(filename, + options, + sg, + s, t, + dsdx, dtdx, dsdy, dtdy, + nchannels, + result); + } + + bool texture3d(ustring filename, + TextureHandle * /*texture_handle*/, + TexturePerthread * /*texture_thread_info*/, + TextureOpt &options, + OSL::ShaderGlobals *sg, + const OSL::Vec3 &P, + const OSL::Vec3 &dPdx, + const OSL::Vec3 &dPdy, + const OSL::Vec3 &dPdz, + int nchannels, + float *result, + float * /*dresultds*/, + float * /*dresultdt*/, + float * /*dresultdr*/) + { + /* TODO(sergey): Support derivatives. */ + return texture3d(filename, + options, + sg, + P, + dPdx, dPdy, dPdz, + nchannels, + result); + } +#endif + bool environment(ustring filename, TextureOpt &options, OSL::ShaderGlobals *sg, const OSL::Vec3 &R, const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp index 8cfe0cbcbd4..2f234aa25ea 100644 --- a/intern/cycles/kernel/osl/osl_shader.cpp +++ b/intern/cycles/kernel/osl/osl_shader.cpp @@ -146,165 +146,175 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag, /* OSL gives us a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { +#else + switch(closure->id) { +#endif + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); + break; + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); + flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); + break; + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - if(prim) { - ShaderClosure sc; + if(prim) { + ShaderClosure sc; #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight*TO_FLOAT3(comp->w); + weight = weight*TO_FLOAT3(comp->w); #endif - sc.weight = weight; + sc.weight = weight; - prim->setup(); + prim->setup(); - switch (prim->category) { - case CClosurePrimitive::BSDF: { - CBSDFClosure *bsdf = (CBSDFClosure *)prim; - int scattering = bsdf->scattering(); + switch(prim->category) { + case CClosurePrimitive::BSDF: { + CBSDFClosure *bsdf = (CBSDFClosure *)prim; + int scattering = bsdf->scattering(); - /* caustic options */ - if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { - KernelGlobals *kg = sd->osl_globals; + /* caustic options */ + if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) { + KernelGlobals *kg = sd->osl_globals; - if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || - (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) { - return; + if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) || + (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) + { + return; + } } - } - /* sample weight */ - float sample_weight = fabsf(average(weight)); + /* sample weight */ + float sample_weight = fabsf(average(weight)); - sc.sample_weight = sample_weight; + sc.sample_weight = sample_weight; - sc.type = bsdf->sc.type; - sc.N = bsdf->sc.N; - sc.T = bsdf->sc.T; - sc.data0 = bsdf->sc.data0; - sc.data1 = bsdf->sc.data1; - sc.data2 = bsdf->sc.data2; - sc.prim = bsdf->sc.prim; + sc.type = bsdf->sc.type; + sc.N = bsdf->sc.N; + sc.T = bsdf->sc.T; + sc.data0 = bsdf->sc.data0; + sc.data1 = bsdf->sc.data1; + sc.data2 = bsdf->sc.data2; + sc.prim = bsdf->sc.prim; - /* add */ - if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= bsdf->shaderdata_flag(); - } - break; - } - case CClosurePrimitive::Emissive: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_EMISSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - /* flag */ - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_EMISSION; - } - break; - } - case CClosurePrimitive::AmbientOcclusion: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_AO; - } - break; - } - case CClosurePrimitive::Holdout: { - sc.sample_weight = 0.0f; - sc.type = CLOSURE_HOLDOUT_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.data2 = 0.0f; - sc.prim = NULL; - - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_HOLDOUT; + /* add */ + if(sc.sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure < MAX_CLOSURE) { + sd->closure[sd->num_closure++] = sc; + sd->flag |= bsdf->shaderdata_flag(); + } + break; } - break; - } - case CClosurePrimitive::BSSRDF: { - CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; - float sample_weight = fabsf(average(weight)); + case CClosurePrimitive::Emissive: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); - if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) { sc.sample_weight = sample_weight; - - sc.type = bssrdf->sc.type; - sc.N = bssrdf->sc.N; - sc.data1 = bssrdf->sc.data1; - sc.T.x = bssrdf->sc.T.x; + sc.type = CLOSURE_EMISSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; sc.prim = NULL; - /* 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) - bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f); - - /* create one closure for each color channel */ - if(fabsf(weight.x) > 0.0f) { - sc.weight = make_float3(weight.x, 0.0f, 0.0f); - sc.data0 = bssrdf->radius.x; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + /* flag */ + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_EMISSION; } + break; + } + case CClosurePrimitive::AmbientOcclusion: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); - if(fabsf(weight.y) > 0.0f) { - sc.weight = make_float3(0.0f, weight.y, 0.0f); - sc.data0 = bssrdf->radius.y; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + sc.sample_weight = sample_weight; + sc.type = CLOSURE_AMBIENT_OCCLUSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; + sc.prim = NULL; + + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_AO; } + break; + } + case CClosurePrimitive::Holdout: { + sc.sample_weight = 0.0f; + sc.type = CLOSURE_HOLDOUT_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.data2 = 0.0f; + sc.prim = NULL; - if(fabsf(weight.z) > 0.0f) { - sc.weight = make_float3(0.0f, 0.0f, weight.z); - sc.data0 = bssrdf->radius.z; - sc.data1 = 0.0f; - sd->flag |= bssrdf_setup(&sc, sc.type); + if(sd->num_closure < MAX_CLOSURE) { sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_HOLDOUT; + } + break; + } + case CClosurePrimitive::BSSRDF: { + CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim; + float sample_weight = fabsf(average(weight)); + + if(sample_weight > CLOSURE_WEIGHT_CUTOFF && sd->num_closure+2 < MAX_CLOSURE) { + sc.sample_weight = sample_weight; + + sc.type = bssrdf->sc.type; + sc.N = bssrdf->sc.N; + sc.data1 = bssrdf->sc.data1; + sc.T.x = bssrdf->sc.T.x; + sc.prim = NULL; + + /* 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) + bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f); + + /* create one closure for each color channel */ + if(fabsf(weight.x) > 0.0f) { + sc.weight = make_float3(weight.x, 0.0f, 0.0f); + sc.data0 = bssrdf->radius.x; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } + + if(fabsf(weight.y) > 0.0f) { + sc.weight = make_float3(0.0f, weight.y, 0.0f); + sc.data0 = bssrdf->radius.y; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } + + if(fabsf(weight.z) > 0.0f) { + sc.weight = make_float3(0.0f, 0.0f, weight.z); + sc.data0 = bssrdf->radius.z; + sc.data1 = 0.0f; + sd->flag |= bssrdf_setup(&sc, sc.type); + sd->closure[sd->num_closure++] = sc; + } } + break; } - break; + case CClosurePrimitive::Background: + case CClosurePrimitive::Volume: + break; /* not relevant */ } - case CClosurePrimitive::Background: - case CClosurePrimitive::Volume: - break; /* not relevant */ } + break; } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_surface_closure_tree(sd, path_flag, add->closureA, weight); - flatten_surface_closure_tree(sd, path_flag, add->closureB, weight); - } } void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) @@ -335,27 +345,33 @@ static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure) * is only one supported closure type at the moment, which has no evaluation * functions, so we just sum the weights */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - - if(prim && prim->category == CClosurePrimitive::Background) -#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - return TO_FLOAT3(comp->w); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { #else - return make_float3(1.0f, 1.0f, 1.0f); + switch(closure->id) { #endif - } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure); + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - return flatten_background_closure_tree(add->closureA) + - flatten_background_closure_tree(add->closureB); + return flatten_background_closure_tree(add->closureA) + + flatten_background_closure_tree(add->closureB); + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); + + if(prim && prim->category == CClosurePrimitive::Background) +#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS + return TO_FLOAT3(comp->w); +#else + return make_float3(1.0f, 1.0f, 1.0f); +#endif + } } return make_float3(0.0f, 0.0f, 0.0f); @@ -390,76 +406,84 @@ static void flatten_volume_closure_tree(ShaderData *sd, /* OSL gives us a closure tree, we flatten it into arrays per * closure type, for evaluation, sampling, etc later on. */ - if(closure->type == OSL::ClosureColor::COMPONENT) { - OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; - CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); +#if OSL_LIBRARY_VERSION_CODE < 10700 + switch(closure->type) { +#else + switch(closure->id) { +#endif + case OSL::ClosureColor::MUL: { + OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; + flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); + break; + } + case OSL::ClosureColor::ADD: { + OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; + flatten_volume_closure_tree(sd, add->closureA, weight); + flatten_volume_closure_tree(sd, add->closureB, weight); + break; + } + default: { + OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure; + CClosurePrimitive *prim = (CClosurePrimitive *)comp->data(); - if(prim) { - ShaderClosure sc; + if(prim) { + ShaderClosure sc; #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS - weight = weight*TO_FLOAT3(comp->w); + weight = weight*TO_FLOAT3(comp->w); #endif - sc.weight = weight; - - prim->setup(); - - switch (prim->category) { - case CClosurePrimitive::Volume: { - CVolumeClosure *volume = (CVolumeClosure *)prim; - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = volume->sc.type; - sc.data0 = volume->sc.data0; - sc.data1 = volume->sc.data1; - - /* add */ - if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) && - (sd->num_closure < MAX_CLOSURE)) - { - sd->closure[sd->num_closure++] = sc; - sd->flag |= volume->shaderdata_flag(); + sc.weight = weight; + + prim->setup(); + + switch(prim->category) { + case CClosurePrimitive::Volume: { + CVolumeClosure *volume = (CVolumeClosure *)prim; + /* sample weight */ + float sample_weight = fabsf(average(weight)); + + sc.sample_weight = sample_weight; + sc.type = volume->sc.type; + sc.data0 = volume->sc.data0; + sc.data1 = volume->sc.data1; + + /* add */ + if((sc.sample_weight > CLOSURE_WEIGHT_CUTOFF) && + (sd->num_closure < MAX_CLOSURE)) + { + sd->closure[sd->num_closure++] = sc; + sd->flag |= volume->shaderdata_flag(); + } + break; } - break; - } - case CClosurePrimitive::Emissive: { - /* sample weight */ - float sample_weight = fabsf(average(weight)); - - sc.sample_weight = sample_weight; - sc.type = CLOSURE_EMISSION_ID; - sc.data0 = 0.0f; - sc.data1 = 0.0f; - sc.prim = NULL; - - /* flag */ - if(sd->num_closure < MAX_CLOSURE) { - sd->closure[sd->num_closure++] = sc; - sd->flag |= SD_EMISSION; + case CClosurePrimitive::Emissive: { + /* sample weight */ + float sample_weight = fabsf(average(weight)); + + sc.sample_weight = sample_weight; + sc.type = CLOSURE_EMISSION_ID; + sc.data0 = 0.0f; + sc.data1 = 0.0f; + sc.prim = NULL; + + /* flag */ + if(sd->num_closure < MAX_CLOSURE) { + sd->closure[sd->num_closure++] = sc; + sd->flag |= SD_EMISSION; + } + break; } - break; + case CClosurePrimitive::Holdout: + break; /* not implemented */ + case CClosurePrimitive::Background: + case CClosurePrimitive::BSDF: + case CClosurePrimitive::BSSRDF: + case CClosurePrimitive::AmbientOcclusion: + break; /* not relevant */ } - case CClosurePrimitive::Holdout: - break; /* not implemented */ - case CClosurePrimitive::Background: - case CClosurePrimitive::BSDF: - case CClosurePrimitive::BSSRDF: - case CClosurePrimitive::AmbientOcclusion: - break; /* not relevant */ } } } - else if(closure->type == OSL::ClosureColor::MUL) { - OSL::ClosureMul *mul = (OSL::ClosureMul *)closure; - flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight); - } - else if(closure->type == OSL::ClosureColor::ADD) { - OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure; - flatten_volume_closure_tree(sd, add->closureA, weight); - flatten_volume_closure_tree(sd, add->closureB, weight); - } } void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx) diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl index e26e8dbff2c..35e01178ba8 100644 --- a/intern/cycles/kernel/shaders/node_brick_texture.osl +++ b/intern/cycles/kernel/shaders/node_brick_texture.osl @@ -22,6 +22,7 @@ float brick_noise(int n) /* fast integer noise */ { int nn; + n = (n + 1013) & 2147483647; n = (n >> 13) ^ n; nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 2147483647; return 0.5 * ((float)nn / 1073741824.0); diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl index 14f0226a0e5..3a0b782c98e 100644 --- a/intern/cycles/kernel/shaders/node_environment_texture.osl +++ b/intern/cycles/kernel/shaders/node_environment_texture.osl @@ -45,6 +45,7 @@ shader node_environment_texture( vector Vector = P, string filename = "", string projection = "Equirectangular", + string interpolation = "linear", string color_space = "sRGB", int is_float = 1, int use_alpha = 1, @@ -64,7 +65,7 @@ shader node_environment_texture( p = environment_texture_direction_to_mirrorball(p); /* todo: use environment for better texture filtering of equirectangular */ - Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "alpha", Alpha); + Color = (color)texture(filename, p[0], 1.0 - p[1], "wrap", "periodic", "interp", interpolation, "alpha", Alpha); if (use_alpha) { Color = color_unpremultiply(Color, Alpha); diff --git a/intern/cycles/kernel/split/kernel_data_init.h b/intern/cycles/kernel/split/kernel_data_init.h index 421e2356f9b..4dab79a5c67 100644 --- a/intern/cycles/kernel/split/kernel_data_init.h +++ b/intern/cycles/kernel/split/kernel_data_init.h @@ -31,7 +31,7 @@ * Un-initialized Ray --------------| |--- Initialized Ray * Un-initialized PathState --------| |--- Initialized PathState * Un-initialized QueueData --------| |--- Initialized QueueData (to QUEUE_EMPTY_SLOT) - * Un-initilaized QueueIndex -------| |--- Initialized QueueIndex (to 0) + * Un-initialized QueueIndex -------| |--- Initialized QueueIndex (to 0) * Un-initialized use_queues_flag---| |--- Initialized use_queues_flag (to false) * Un-initialized ray_state --------| |--- Initialized ray_state * parallel_samples --------------- | |--- Initialized per_sample_output_buffers @@ -383,7 +383,7 @@ ccl_device void kernel_data_init( &Ray_coop[ray_index]); if(Ray_coop[ray_index].t != 0.0f) { - /* Initialize throuput, L_transparent, Ray, PathState; + /* Initialize throughput, L_transparent, Ray, PathState; * These rays proceed with path-iteration. */ throughput_coop[ray_index] = make_float3(1.0f, 1.0f, 1.0f); diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h index 025ae96f59d..63bbb27d873 100644 --- a/intern/cycles/kernel/svm/svm_attribute.h +++ b/intern/cycles/kernel/svm/svm_attribute.h @@ -22,6 +22,8 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeType *type, NodeAttributeType *mesh_type, AttributeElement *elem, int *offset, uint *out_offset) { + *out_offset = node.z; + *type = (NodeAttributeType)node.w; if(ccl_fetch(sd, object) != OBJECT_NONE) { /* find attribute by unique id */ uint id = node.y; @@ -32,6 +34,12 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset); while(attr_map.x != id) { + if(UNLIKELY(attr_map.x == ATTR_STD_NONE)) { + *elem = ATTR_ELEMENT_NONE; + *offset = 0; + *mesh_type = (NodeAttributeType)node.w; + return; + } attr_offset += ATTR_PRIM_TYPES; attr_map = kernel_tex_fetch(__attributes_map, attr_offset); } @@ -47,9 +55,6 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd, *offset = 0; *mesh_type = (NodeAttributeType)node.w; } - - *out_offset = node.z; - *type = (NodeAttributeType)node.w; } ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h index fcf8f47b77e..9b0cf5ab8c4 100644 --- a/intern/cycles/kernel/svm/svm_brick.h +++ b/intern/cycles/kernel/svm/svm_brick.h @@ -21,6 +21,7 @@ CCL_NAMESPACE_BEGIN ccl_device_noinline float brick_noise(int n) /* fast integer noise */ { int nn; + n = (n + 1013) & 0x7fffffff; n = (n >> 13) ^ n; nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff; return 0.5f * ((float)nn / 1073741824.0f); diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 20105fd84f0..2120c892490 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -63,6 +63,9 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, C if(ccl_fetch(sd, num_closure) < MAX_CLOSURE) { sc->weight *= mix_weight; sc->type = type; + sc->data0 = 0.0f; + sc->data1 = 0.0f; + sc->data2 = 0.0f; #ifdef __OSL__ sc->prim = NULL; #endif @@ -408,7 +411,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * sc->data1 = param2; sc->data2 = -stack_load_float(stack, data_node.z); - if(!(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)) { + if(stack_valid(data_node.y)) { + sc->T = normalize(stack_load_float3(stack, data_node.y)); + } + else if(!(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)) { sc->T = normalize(ccl_fetch(sd, dPdv)); sc->data2 = 0.0f; } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 641d30a5737..bf7e067616f 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -46,7 +46,7 @@ CCL_NAMESPACE_BEGIN #define NODE_FEATURE_HAIR (1 << 1) #define NODE_FEATURE_BUMP (1 << 2) /* TODO(sergey): Consider using something like ((uint)(-1)). - * Need to ceck carefully operand types around usage of this + * Need to check carefully operand types around usage of this * define first. */ #define NODE_FEATURE_ALL (NODE_FEATURE_VOLUME|NODE_FEATURE_HAIR|NODE_FEATURE_BUMP) diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h index bbb687dfce5..31cad5ec887 100644 --- a/intern/cycles/kernel/svm/svm_voxel.h +++ b/intern/cycles/kernel/svm/svm_voxel.h @@ -43,15 +43,6 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg, tfm.w = read_node_float(kg, offset); co = transform_point(&tfm, co); } - if(co.x < 0.0f || co.y < 0.0f || co.z < 0.0f || - co.x > 1.0f || co.y > 1.0f || co.z > 1.0f) - { - if (stack_valid(density_out_offset)) - stack_store_float(stack, density_out_offset, 0.0f); - if (stack_valid(color_out_offset)) - stack_store_float3(stack, color_out_offset, make_float3(0.0f, 0.0f, 0.0f)); - return; - } float4 r = kernel_tex_image_interp_3d(id, co.x, co.y, co.z); if (stack_valid(density_out_offset)) stack_store_float(stack, density_out_offset, r.w); diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index df2a1d348d6..88ff7fbb70a 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN Camera::Camera() { shuttertime = 1.0f; + motion_position = MOTION_POSITION_CENTER; aperturesize = 0.0f; focaldistance = 10.0f; @@ -53,6 +54,7 @@ Camera::Camera() longitude_min = -M_PI_F; longitude_max = M_PI_F; fov = M_PI_4_F; + fov_pre = fov_post = fov; sensorwidth = 0.036f; sensorheight = 0.024f; @@ -91,19 +93,26 @@ Camera::~Camera() void Camera::compute_auto_viewplane() { - float aspect = (float)width/(float)height; - - if(width >= height) { - viewplane.left = -aspect; - viewplane.right = aspect; - viewplane.bottom = -1.0f; + if(type == CAMERA_PANORAMA) { + viewplane.left = 0.0f; + viewplane.right = 1.0f; + viewplane.bottom = 0.0f; viewplane.top = 1.0f; } else { - viewplane.left = -1.0f; - viewplane.right = 1.0f; - viewplane.bottom = -1.0f/aspect; - viewplane.top = 1.0f/aspect; + float aspect = (float)width/(float)height; + if(width >= height) { + viewplane.left = -aspect; + viewplane.right = aspect; + viewplane.bottom = -1.0f; + viewplane.top = 1.0f; + } + else { + viewplane.left = -1.0f; + viewplane.right = 1.0f; + viewplane.bottom = -1.0f/aspect; + viewplane.top = 1.0f/aspect; + } } } @@ -417,9 +426,9 @@ BoundBox Camera::viewplane_bounds_get() BoundBox bounds = BoundBox::empty; if(type == CAMERA_PANORAMA) { - bounds.grow(make_float3(cameratoworld.w.x, - cameratoworld.w.y, - cameratoworld.w.z)); + bounds.grow(make_float3(cameratoworld.x.w, + cameratoworld.y.w, + cameratoworld.z.w)); } else { bounds.grow(transform_raster_to_world(0.0f, 0.0f)); diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 1bedb051112..53bd4f0bc14 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -32,12 +32,24 @@ class Scene; /* Camera * * The camera parameters are quite standard, tested to be both compatible with - * Renderman, and Blender after remapping. */ + * Renderman, and Blender after remapping. + */ class Camera { public: + /* Specifies an offset for the shutter's time interval. */ + enum MotionPosition { + /* Shutter opens at the current frame. */ + MOTION_POSITION_START, + /* Shutter is fully open at the current frame. */ + MOTION_POSITION_CENTER, + /* Shutter closes at the current frame. */ + MOTION_POSITION_END, + }; + /* motion blur */ float shuttertime; + MotionPosition motion_position; /* depth of field */ float focaldistance; diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index 7282b04a22e..58080289633 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -144,7 +144,13 @@ void Pass::add(PassType type, vector<Pass>& passes) pass.exposure = false; break; case PASS_LIGHT: - /* ignores */ + /* This isn't a real pass, used by baking to see whether + * light data is needed or not. + * + * Set components to 0 so pass sort below happens in a + * determined way. + */ + pass.components = 0; break; #ifdef WITH_CYCLES_DEBUG case PASS_BVH_TRAVERSAL_STEPS: diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index e0537101247..f5ff091623b 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -336,6 +336,8 @@ void ShaderGraph::remove_unneeded_nodes() vector<bool> removed(num_node_ids, false); bool any_node_removed = false; + ShaderNode *geom = NULL; + /* find and unlink proxy nodes */ foreach(ShaderNode *node, nodes) { if(node->special_type == SHADER_SPECIAL_TYPE_PROXY) { @@ -423,12 +425,19 @@ void ShaderGraph::remove_unneeded_nodes() BumpNode *bump = static_cast<BumpNode*>(node); if(bump->outputs[0]->links.size()) { - /* Height input not connected */ - /* ToDo: Strength zero? */ - if(!bump->inputs[0]->link) { + /* Height inputs is not connected. */ + /* TODO(sergey): Ignore bump with zero strength. */ + if(bump->inputs[0]->link == NULL) { vector<ShaderInput*> inputs = bump->outputs[0]->links; - - relink(bump->inputs, inputs, NULL); + if(bump->inputs[4]->link == NULL) { + if(geom == NULL) { + geom = new GeometryNode(); + } + relink(bump->inputs, inputs, geom->output("Normal")); + } + else { + relink(bump->inputs, inputs, bump->input("Normal")->link); + } removed[bump->id] = true; any_node_removed = true; } @@ -511,6 +520,10 @@ void ShaderGraph::remove_unneeded_nodes() nodes = newnodes; } + + if(geom != NULL) { + add(geom); + } } void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack) diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 7bceb8a8bfa..486ae5b597f 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -69,6 +69,9 @@ void ImageManager::set_extended_image_limits(const DeviceInfo& info) else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.extended_images) { tex_num_images = TEX_EXTENDED_NUM_IMAGES_GPU; } + else if(info.pack_images) { + tex_num_images = TEX_PACKED_NUM_IMAGES; + } } bool ImageManager::set_animation_frame_update(int frame) @@ -447,6 +450,9 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) /* read RGBA pixels */ uchar *pixels = (uchar*)tex_img.resize(width, height, depth); + if(pixels == NULL) { + return false; + } bool cmyk = false; if(in) { @@ -570,6 +576,9 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ /* read RGBA pixels */ float *pixels = (float*)tex_img.resize(width, height, depth); + if(pixels == NULL) { + return false; + } bool cmyk = false; if(in) { diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index bcc58ae951b..c79c152afde 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -40,6 +40,13 @@ CCL_NAMESPACE_BEGIN #define TEX_EXTENDED_NUM_IMAGES_CPU 1024 #define TEX_EXTENDED_IMAGE_BYTE_START TEX_EXTENDED_NUM_FLOAT_IMAGES +/* Limitations for packed images. + * + * Technically number of textures is unlimited, but it should in + * fact be in sync with CPU limitations. + */ +#define TEX_PACKED_NUM_IMAGES 1024 + /* color to use when textures are not found */ #define TEX_IMAGE_MISSING_R 1 #define TEX_IMAGE_MISSING_G 0 diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 465d7ea02c6..9f8d5b50ccd 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -100,6 +100,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene * transparent shaders in the scene. Otherwise we can disable it * to improve performance a bit. */ if(transparent_shadows) { + kintegrator->transparent_shadows = false; foreach(Shader *shader, scene->shaders) { /* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */ if((shader->has_surface_transparent && shader->use_transparent_shadow) || shader->has_volume) { diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 45685fe5927..57f194651f8 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -513,7 +513,6 @@ void Mesh::compute_bvh(SceneParams *params, Progress *progress, int n, int total progress->set_status(msg, "Building BVH"); BVHParams bparams; - bparams.use_cache = params->use_bvh_cache; bparams.use_spatial_split = params->use_bvh_spatial_split; bparams.use_qbvh = params->use_qbvh; @@ -1084,7 +1083,6 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene * bparams.top_level = true; bparams.use_qbvh = scene->params.use_qbvh; bparams.use_spatial_split = scene->params.use_bvh_spatial_split; - bparams.use_cache = scene->params.use_bvh_cache; delete bvh; bvh = BVH::create(bparams, scene->objects); diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp index 1ba0c7f7291..801fffc774c 100644 --- a/intern/cycles/render/mesh_displace.cpp +++ b/intern/cycles/render/mesh_displace.cpp @@ -78,7 +78,7 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me int prim = mesh->tri_offset + i; float u, v; - switch (j) { + switch(j) { case 0: u = 1.0f; v = 0.0f; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 7ed07ab6453..7ac872b8416 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -182,6 +182,21 @@ static ShaderEnum image_projection_init() return enm; } +static const char* get_osl_interpolation_parameter(InterpolationType interpolation) +{ + switch(interpolation) { + case INTERPOLATION_CLOSEST: + return "closest"; + case INTERPOLATION_CUBIC: + return "cubic"; + case INTERPOLATION_SMART: + return "smart"; + case INTERPOLATION_LINEAR: + default: + return "linear"; + } +} + ShaderEnum ImageTextureNode::color_space_enum = color_space_init(); ShaderEnum ImageTextureNode::projection_enum = image_projection_init(); @@ -362,22 +377,7 @@ void ImageTextureNode::compile(OSLCompiler& compiler) compiler.parameter("projection_blend", projection_blend); compiler.parameter("is_float", is_float); compiler.parameter("use_alpha", !alpha_out->links.empty()); - - switch (interpolation) { - case INTERPOLATION_CLOSEST: - compiler.parameter("interpolation", "closest"); - break; - case INTERPOLATION_CUBIC: - compiler.parameter("interpolation", "cubic"); - break; - case INTERPOLATION_SMART: - compiler.parameter("interpolation", "smart"); - break; - case INTERPOLATION_LINEAR: - default: - compiler.parameter("interpolation", "linear"); - break; - } + compiler.parameter("interpolation", get_osl_interpolation_parameter(interpolation)); switch(extension) { case EXTENSION_EXTEND: @@ -421,6 +421,7 @@ EnvironmentTextureNode::EnvironmentTextureNode() filename = ""; builtin_data = NULL; color_space = ustring("Color"); + interpolation = INTERPOLATION_LINEAR; projection = ustring("Equirectangular"); animated = false; @@ -434,7 +435,7 @@ EnvironmentTextureNode::~EnvironmentTextureNode() if(image_manager) { image_manager->remove_image(filename, builtin_data, - INTERPOLATION_LINEAR, + interpolation, EXTENSION_REPEAT); } } @@ -477,7 +478,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) 0, is_float_bool, is_linear, - INTERPOLATION_LINEAR, + interpolation, EXTENSION_REPEAT, use_alpha); is_float = (int)is_float_bool; @@ -546,7 +547,7 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler) 0, is_float_bool, is_linear, - INTERPOLATION_LINEAR, + interpolation, EXTENSION_REPEAT, use_alpha); is_float = (int)is_float_bool; @@ -564,6 +565,9 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler) compiler.parameter("color_space", "Linear"); else compiler.parameter("color_space", "sRGB"); + + compiler.parameter("interpolation", get_osl_interpolation_parameter(interpolation)); + compiler.parameter("is_float", is_float); compiler.parameter("use_alpha", !alpha_out->links.empty()); compiler.add(this, "node_environment_texture"); @@ -1381,7 +1385,7 @@ PointDensityTextureNode::~PointDensityTextureNode() image_manager->remove_image(filename, builtin_data, interpolation, - EXTENSION_REPEAT); + EXTENSION_CLIP); } } @@ -1413,10 +1417,10 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler) image_manager = compiler.image_manager; - if (use_density || use_color) { - if (use_density) + if(use_density || use_color) { + if(use_density) compiler.stack_assign(density_out); - if (use_color) + if(use_color) compiler.stack_assign(color_out); if(slot == -1) { @@ -1425,7 +1429,7 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler) false, 0, is_float, is_linear, interpolation, - EXTENSION_REPEAT, + EXTENSION_CLIP, true); } @@ -1466,14 +1470,14 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler) image_manager = compiler.image_manager; - if (use_density || use_color) { + if(use_density || use_color) { if(slot == -1) { bool is_float, is_linear; slot = image_manager->add_image(filename, builtin_data, false, 0, is_float, is_linear, interpolation, - EXTENSION_REPEAT, + EXTENSION_CLIP, true); } @@ -1484,7 +1488,7 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler) compiler.parameter("mapping", transform_transpose(tfm)); compiler.parameter("use_mapping", 1); } - switch (interpolation) { + switch(interpolation) { case INTERPOLATION_CLOSEST: compiler.parameter("interpolation", "closest"); break; @@ -1675,7 +1679,7 @@ void ConvertNode::compile(SVMCompiler& compiler) compiler.stack_assign(in); compiler.stack_assign(out); - compiler.add_node(NODE_VALUE_V, in->stack_offset); + compiler.add_node(NODE_VALUE_V, out->stack_offset); compiler.add_node(NODE_VALUE_V, in->value); } } @@ -2354,6 +2358,7 @@ HairBsdfNode::HairBsdfNode() add_input("Offset", SHADER_SOCKET_FLOAT); add_input("RoughnessU", SHADER_SOCKET_FLOAT); add_input("RoughnessV", SHADER_SOCKET_FLOAT); + add_input("Tangent", SHADER_SOCKET_VECTOR); } void HairBsdfNode::compile(SVMCompiler& compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 5065e68345a..39709c26398 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -116,6 +116,7 @@ public: void *builtin_data; ustring color_space; ustring projection; + InterpolationType interpolation; bool animated; static ShaderEnum color_space_enum; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 31be2a3d3f4..aba3e7237d2 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -18,6 +18,7 @@ #include "camera.h" #include "device.h" #include "graph.h" +#include "integrator.h" #include "light.h" #include "mesh.h" #include "nodes.h" @@ -338,6 +339,7 @@ void ShaderManager::device_update_common(Device *device, uint *shader_flag = dscene->shader_flag.resize(shader_flag_size); uint i = 0; bool has_volumes = false; + bool has_transparent_shadow = false; foreach(Shader *shader, scene->shaders) { uint flag = 0; @@ -355,8 +357,8 @@ void ShaderManager::device_update_common(Device *device, flag |= SD_HAS_ONLY_VOLUME; /* todo: this could check more fine grained, to skip useless volumes - * enclosed inside an opaque bsdf, although we still need to handle - * the case with camera inside volumes too */ + * enclosed inside an opaque bsdf. + */ flag |= SD_HAS_TRANSPARENT_SHADOW; } if(shader->heterogeneous_volume && shader->has_heterogeneous_volume) @@ -382,6 +384,8 @@ void ShaderManager::device_update_common(Device *device, shader_flag[i++] = flag; shader_flag[i++] = shader->pass_id; + + has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW); } device->tex_alloc("__shader_flag", dscene->shader_flag); @@ -404,6 +408,10 @@ void ShaderManager::device_update_common(Device *device, /* integrator */ KernelIntegrator *kintegrator = &dscene->data.integrator; kintegrator->use_volumes = has_volumes; + /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */ + if(scene->integrator->transparent_shadows) { + kintegrator->transparent_shadows = has_transparent_shadow; + } } void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene) diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index d0bd34915df..e81b2f3a827 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -121,7 +121,7 @@ int SVMCompiler::stack_size(ShaderSocketType type) { int size = 0; - switch (type) { + switch(type) { case SHADER_SOCKET_FLOAT: case SHADER_SOCKET_INT: size = 1; @@ -624,7 +624,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty ShaderNode *node = graph->output(); ShaderInput *clin = NULL; - switch (type) { + switch(type) { case SHADER_TYPE_SURFACE: clin = node->input("Surface"); break; @@ -654,7 +654,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty if(clin->link) { bool generate = false; - switch (type) { + switch(type) { case SHADER_TYPE_SURFACE: /* generate surface shader */ generate = true; shader->has_surface = true; diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index 7e68ce84d94..1bec39431d8 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -199,7 +199,7 @@ list<Tile>::iterator TileManager::next_background_tile(int device, TileOrder til int64_t distx = cordx; int64_t disty = cordy; - switch (tile_order) { + switch(tile_order) { case TILE_CENTER: distx = centx - (cur_tile.x + (cur_tile.w / 2)); disty = centy - (cur_tile.y + (cur_tile.h / 2)); diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index 97c93516496..7d6dfd34e0e 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -1447,14 +1447,9 @@ ccl_device bool ray_triangle_intersect_uv( return true; } -#if defined(__KERNEL_CUDA__) && (defined(i386) || defined(_M_IX86)) && (defined(__KERNEL_EXPERIMENTAL__) || __CUDA_ARCH__ == 500) -ccl_device_noinline -#else -ccl_device -#endif -bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t, - float3 quad_P, float3 quad_u, float3 quad_v, - float3 *isect_P, float *isect_t) +ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_t, + float3 quad_P, float3 quad_u, float3 quad_v, + float3 *isect_P, float *isect_t) { float3 v0 = quad_P - quad_u*0.5f - quad_v*0.5f; float3 v1 = quad_P + quad_u*0.5f - quad_v*0.5f; diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h index c951c35fc76..42d3ca69b3a 100644 --- a/intern/cycles/util/util_optimization.h +++ b/intern/cycles/util/util_optimization.h @@ -101,7 +101,7 @@ #ifdef _MSC_VER #include <intrin.h> -#else +#elif (defined(__x86_64__) || defined(__i386__)) #include <x86intrin.h> #endif diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index ba8d04b5c16..f01db64a79b 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -347,7 +347,12 @@ ccl_device_inline Transform transform_quick_inverse(Transform M) * scale can be inverted but what about shearing? */ Transform R; float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z); - + if(det == 0.0f) { + M.x.x += 1e-8f; + M.y.y += 1e-8f; + M.z.z += 1e-8f; + det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z); + } det = (det != 0.0f)? 1.0f/det: 0.0f; float3 Rx = det*make_float3(M.z.z*M.y.y - M.z.y*M.y.z, M.z.y*M.x.z - M.z.z*M.x.y, M.y.z*M.x.y - M.y.y*M.x.z); diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h index 15a65be0ef0..623436483a0 100644 --- a/intern/cycles/util/util_vector.h +++ b/intern/cycles/util/util_vector.h @@ -105,6 +105,7 @@ public: { data = NULL; datasize = 0; + capacity = 0; } array(size_t newsize) @@ -112,10 +113,12 @@ public: if(newsize == 0) { data = NULL; datasize = 0; + capacity = 0; } else { data = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment); datasize = newsize; + capacity = datasize; } } @@ -129,11 +132,13 @@ public: if(from.datasize == 0) { data = NULL; datasize = 0; + capacity = 0; } else { data = (T*)util_aligned_malloc(sizeof(T)*from.datasize, alignment); memcpy(data, from.data, from.datasize*sizeof(T)); datasize = from.datasize; + capacity = datasize; } return *this; @@ -142,6 +147,7 @@ public: array& operator=(const vector<T>& from) { datasize = from.size(); + capacity = datasize; data = NULL; if(datasize > 0) { @@ -157,28 +163,39 @@ public: util_aligned_free(data); } - void resize(size_t newsize) + T* resize(size_t newsize) { if(newsize == 0) { clear(); } else if(newsize != datasize) { - T *newdata = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment); - if(data) { - memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T)); - util_aligned_free(data); + if(newsize > capacity) { + T *newdata = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment); + if(newdata == NULL) { + /* Allocation failed, likely out of memory. */ + clear(); + return NULL; + } + else if(data) { + memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T)); + util_aligned_free(data); + } + data = newdata; + capacity = newsize; } - - data = newdata; datasize = newsize; } + return data; } void clear() { - util_aligned_free(data); - data = NULL; + if(data != NULL) { + util_aligned_free(data); + data = NULL; + } datasize = 0; + capacity = 0; } size_t size() const @@ -192,9 +209,22 @@ public: return data[i]; } + void reserve(size_t newcapacity) { + if(newcapacity > capacity) { + T *newdata = (T*)util_aligned_malloc(sizeof(T)*newcapacity, alignment); + if(data) { + memcpy(newdata, data, ((datasize < newcapacity)? datasize: newcapacity)*sizeof(T)); + util_aligned_free(data); + } + data = newdata; + capacity = newcapacity; + } + } + protected: T *data; size_t datasize; + size_t capacity; }; CCL_NAMESPACE_END diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp index 99c3b170634..f2f928f07dc 100644 --- a/intern/elbeem/intern/simulation_object.cpp +++ b/intern/elbeem/intern/simulation_object.cpp @@ -172,7 +172,7 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob) mpLbm->setParticleTracer( mpParts ); if(mpElbeemSettings) { // set further settings from API struct init - if(mpElbeemSettings->outputPath) this->mOutFilename = string(mpElbeemSettings->outputPath); + this->mOutFilename = string(mpElbeemSettings->outputPath); mpLbm->initDomainTrafo( mpElbeemSettings->surfaceTrafo ); mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing); mpLbm->setIsoSubdivs(mpElbeemSettings->surfaceSubdivs); diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 025559e11a4..78566210047 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -48,7 +48,8 @@ sources.remove('intern' + os.sep + 'GHOST_ContextWGL.cpp') pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_SystemPaths', 'GHOST_Window', 'GHOST_DropTarget', 'GHOST_NDOFManager', 'GHOST_Context'] -defs = env['BF_GL_DEFINITIONS'] +defs = [] +defs += env['BF_GL_DEFINITIONS'] if env['WITH_BF_GL_EGL']: defs.append('WITH_EGL') diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index af992bf5a3c..9baa66abad9 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -358,27 +358,20 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, int bounds[4], const int mouse_ungrab_xy[2]) { GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - GHOST_Rect bounds_rect, bounds_win; - GHOST_TInt32 mouse_ungrab_xy_global[2]; + GHOST_Rect bounds_rect; + GHOST_TInt32 mouse_xy[2]; if (bounds) { - /* if this is X11 specific we need a function that converts */ - window->getClientBounds(bounds_win); - window->clientToScreen(bounds[0], bounds_win.getHeight() - bounds[1], bounds_rect.m_l, bounds_rect.m_t); - window->clientToScreen(bounds[2], bounds_win.getHeight() - bounds[3], bounds_rect.m_r, bounds_rect.m_b); - + bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]); } - if (mouse_ungrab_xy) { - if (bounds == NULL) - window->getClientBounds(bounds_win); - window->clientToScreen(mouse_ungrab_xy[0], bounds_win.getHeight() - mouse_ungrab_xy[1], - mouse_ungrab_xy_global[0], mouse_ungrab_xy_global[1]); + mouse_xy[0] = mouse_ungrab_xy[0]; + mouse_xy[1] = mouse_ungrab_xy[1]; } return window->setCursorGrab(mode, bounds ? &bounds_rect : NULL, - mouse_ungrab_xy ? mouse_ungrab_xy_global : NULL); + mouse_ungrab_xy ? mouse_xy : NULL); } diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index 92fdbfc53de..953235669a8 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -128,18 +128,9 @@ public: private: //void initContextCGLEW() - /** The window containing the OpenGL view */ - NSWindow *m_window; - /** The openGL view */ NSOpenGLView *m_openGLView; - const int m_contextProfileMask; - const int m_contextMajorVersion; - const int m_contextMinorVersion; - const int m_contextFlags; - const int m_contextResetNotificationStrategy; - /** The OpenGL drawing context */ NSOpenGLContext *m_openGLContext; diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm index 51895e5fa1a..6a9c23ea72b 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.mm +++ b/intern/ghost/intern/GHOST_ContextCGL.mm @@ -58,16 +58,9 @@ GHOST_ContextCGL::GHOST_ContextCGL( int contextFlags, int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), - m_window(window), m_openGLView(openGLView), - m_contextProfileMask(contextProfileMask), - m_contextMajorVersion(contextMajorVersion), - m_contextMinorVersion(contextMinorVersion), - m_contextFlags(contextFlags), - m_contextResetNotificationStrategy(contextResetNotificationStrategy), m_openGLContext(nil) { - assert(window != nil); assert(openGLView != nil); } diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index 3cce2236143..0ee8da15dea 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -40,6 +40,13 @@ #include <cstdio> #include <cstring> +/* needed for intel drivers (works w/ mesa-swrast & nvidia) */ +#define USE_GLXEW_INIT_WORKAROUND + +#ifdef USE_GLXEW_INIT_WORKAROUND +static GLuint _glewStrLen(const GLubyte *s); +static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end); +#endif #ifdef WITH_GLEW_MX GLXEWContext *glxewContext = NULL; @@ -154,10 +161,54 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); #endif - /* needed so 'GLXEW_ARB_create_context' is valid */ - mxIgnoreNoVersion(1); - initContextGLXEW(); - mxIgnoreNoVersion(0); + + + /* -------------------------------------------------------------------- */ + /* Begin Inline Glew */ + +#ifdef USE_GLXEW_INIT_WORKAROUND + const GLubyte *extStart = (GLubyte *)""; + const GLubyte *extEnd; + if (glXQueryExtension(m_display, NULL, NULL)) { + extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS); + if ((extStart == NULL) || + (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB( + (const GLubyte *)"glXChooseFBConfig")) == NULL || + (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB( + (const GLubyte *)"glXCreateContextAttribsARB")) == NULL) + { + extStart = (GLubyte *)""; + } + } + extEnd = extStart + _glewStrLen(extStart); + +#undef GLXEW_ARB_create_context + const bool GLXEW_ARB_create_context = + _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd); +#undef GLXEW_ARB_create_context_profile + const bool GLXEW_ARB_create_context_profile = + _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd); +#undef GLXEW_ARB_create_context_robustness +const bool GLXEW_ARB_create_context_robustness = + _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd); +#ifdef WITH_GLEW_ES +#undef GLXEW_EXT_create_context_es_profile + const bool GLXEW_EXT_create_context_es_profile = + _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd); +#undef GLXEW_EXT_create_context_es2_profile + const bool GLXEW_EXT_create_context_es2_profile = + _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd); +#endif /* WITH_GLEW_ES */ + + /* End Inline Glew */ + /* -------------------------------------------------------------------- */ +#else + /* important to initialize only glxew (_not_ glew), + * since this breaks w/ Mesa's `swrast`, see: T46431 */ + glxewInit(); +#endif /* USE_GLXEW_INIT_WORKAROUND */ + + if (GLXEW_ARB_create_context) { int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB; @@ -246,6 +297,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() if (framebuffer_config) { m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs); + XFree(framebuffer_config); } } else { @@ -263,6 +315,10 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() glXMakeCurrent(m_display, m_window, m_context); + // Seems that this has to be called after MakeCurrent, + // which means we cannot use glX extensions until after we create a context + initContextGLXEW(); + initClearGL(); ::glXSwapBuffers(m_display, m_window); @@ -404,5 +460,49 @@ int GHOST_X11_GL_GetAttributes( GHOST_ASSERT(i <= attribs_max, "attribute size too small"); + (void)attribs_max; + return i; } + + +/* excuse inlining part of glew */ +#ifdef USE_GLXEW_INIT_WORKAROUND +static GLuint _glewStrLen(const GLubyte *s) +{ + GLuint i = 0; + if (s == NULL) return 0; + while (s[i] != '\0') i++; + return i; +} + +static GLuint _glewStrCLen(const GLubyte *s, GLubyte c) +{ + GLuint i = 0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) i++; + return (s[i] == '\0' || s[i] == c) ? i : 0; +} + +static GLboolean _glewStrSame(const GLubyte *a, const GLubyte *b, GLuint n) +{ + GLuint i = 0; + if (a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; + return i == n ? GL_TRUE : GL_FALSE; +} + +static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end) +{ + const GLubyte *p; + GLuint len = _glewStrLen((const GLubyte *)name); + p = start; + while (p < end) { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte *)name, p, n)) return GL_TRUE; + p += n + 1; + } + return GL_FALSE; +} +#endif /* USE_GLXEW_INIT_WORKAROUND */
\ No newline at end of file diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp index 0cc116292c0..b3e6f2e53fa 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp @@ -117,7 +117,7 @@ getDisplaySetting( if (dpy == NULL) return GHOST_kFailure; - (void) display; + (void)display; #ifdef WITH_X11_XF86VMODE int majorVersion, minorVersion; @@ -149,6 +149,7 @@ getDisplaySetting( GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); + (void)index; setting.xPixels = DisplayWidth(dpy, DefaultScreen(dpy)); setting.yPixels = DisplayHeight(dpy, DefaultScreen(dpy)); @@ -267,6 +268,8 @@ setCurrentDisplaySetting( return GHOST_kSuccess; #else + (void)setting; + /* Just pretend the request was successful. */ return GHOST_kSuccess; #endif diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 3d6b40ee541..cfddd5b3781 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -297,9 +297,8 @@ protected: */ GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y; - /** Multitouch trackpad availability */ - bool m_hasMultiTouchTrackpad; - + /** Temporarily ignore momentum scroll events */ + bool m_ignoreMomentumScroll; }; #endif // __GHOST_SYSTEMCOCOA_H__ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index b9686e5af9b..a3c48ff3b2d 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -284,7 +284,7 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) * CocoaAppDelegate * ObjC object to capture applicationShouldTerminate, and send quit event **/ -@interface CocoaAppDelegate : NSObject { +@interface CocoaAppDelegate : NSObject <NSFileManagerDelegate> { GHOST_SystemCocoa *systemCocoa; } - (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa; @@ -370,12 +370,11 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() rstring = (char*)malloc( len ); sysctl( mib, 2, rstring, &len, NULL, 0 ); - m_hasMultiTouchTrackpad = false; - free( rstring ); rstring = NULL; m_ignoreWindowSizedMessages = false; + m_ignoreMomentumScroll = false; } GHOST_SystemCocoa::~GHOST_SystemCocoa() @@ -1223,10 +1222,10 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) NSEvent *event = (NSEvent *)eventPtr; switch ([event subtype]) { - case NX_SUBTYPE_TABLET_POINT: + case NSTabletPointEventSubtype: handleTabletEvent(eventPtr, NSTabletPoint); return true; - case NX_SUBTYPE_TABLET_PROXIMITY: + case NSTabletProximityEventSubtype: handleTabletEvent(eventPtr, NSTabletProximity); return true; default: @@ -1317,6 +1316,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y; window->getCursorGrabInitPos(x_warp, y_warp); + window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp); window->getCursorGrabAccum(x_accum, y_accum); x_accum += [event deltaX]; @@ -1368,6 +1368,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) //Post event window->getCursorGrabInitPos(x_cur, y_cur); + window->screenToClientIntern(x_cur, y_cur, x_cur, y_cur); window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y); pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); break; @@ -1388,25 +1389,36 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } } break; - - /* these events only happen on swiping trackpads or tablets */ - /* warning: using tablet + trackpad at same time frustrates this static variable */ - case NSEventTypeBeginGesture: - m_hasMultiTouchTrackpad = 1; - break; - case NSEventTypeEndGesture: - m_hasMultiTouchTrackpad = 0; - break; - + case NSScrollWheel: { - int *momentum = NULL; + NSEventPhase momentumPhase = NSEventPhaseNone; + NSEventPhase phase = NSEventPhaseNone; + bool hasMultiTouch = false; if ([event respondsToSelector:@selector(momentumPhase)]) - momentum = (int *)[event momentumPhase]; + momentumPhase = [event momentumPhase]; + if ([event respondsToSelector:@selector(phase)]) + phase = [event phase]; + if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)]) + hasMultiTouch = [event hasPreciseScrollingDeltas]; + + /* when pressing a key while momentum scrolling continues after + * lifting fingers off the trackpad, the action can unexpectedly + * change from e.g. scrolling to zooming. this works around the + * issue by ignoring momentum scroll after a key press */ + if (momentumPhase) + { + if (m_ignoreMomentumScroll) + break; + } + else + { + m_ignoreMomentumScroll = false; + } /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */ - if (!m_hasMultiTouchTrackpad && momentum == NULL) { + if (!hasMultiTouch && momentumPhase == NSEventPhaseNone) { GHOST_TInt32 delta; double deltaF = [event deltaY]; @@ -1422,16 +1434,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_TInt32 x, y; double dx; double dy; - + #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 - int phase = [event phase]; - /* with 10.7 nice scrolling deltas are supported */ dx = [event scrollingDeltaX]; dy = [event scrollingDeltaY]; /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */ - if (phase == 0 && momentum==NULL) { + if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) { dx = [event deltaX]; dy = [event deltaY]; } @@ -1566,6 +1576,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) pushEvent( new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL) ); //printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf); } + m_ignoreMomentumScroll = true; break; case NSFlagsChanged: @@ -1585,6 +1596,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) } m_modifierMask = modifiers; + m_ignoreMomentumScroll = true; break; default: diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index f1f38cc14b3..38813e14a1b 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -393,16 +393,6 @@ enum { systemCocoa->handleMouseEvent(event); } -- (void)beginGestureWithEvent:(NSEvent *)event -{ - systemCocoa->handleMouseEvent(event); -} - -- (void)endGestureWithEvent:(NSEvent *)event -{ - systemCocoa->handleMouseEvent(event); -} - - (void)tabletPoint:(NSEvent *)event { systemCocoa->handleTabletEvent(event,[event type]); @@ -1195,18 +1185,18 @@ GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType ty #if defined(WITH_GL_PROFILE_CORE) GHOST_Context *context = new GHOST_ContextCGL( - m_initStereoVisual, - m_initNumOfAASamples, + m_wantStereoVisual, + m_wantNumOfAASamples, m_window, m_openGLView, - CGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + GL_CONTEXT_CORE_PROFILE_BIT, 3, 2, GHOST_OPENGL_CGL_CONTEXT_FLAGS, GHOST_OPENGL_CGL_RESET_NOTIFICATION_STRATEGY); #elif defined(WITH_GL_PROFILE_ES20) GHOST_Context *context = new GHOST_ContextCGL( - m_initStereoVisual, - m_initNumOfAASamples, + m_wantStereoVisual, + m_wantNumOfAASamples, m_window, m_openGLView, CGL_CONTEXT_ES2_PROFILE_BIT_EXT, @@ -1463,12 +1453,9 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode if (mode != GHOST_kGrabDisable) { //No need to perform grab without warp as it is always on in OS X if (mode != GHOST_kGrabNormal) { - GHOST_TInt32 x_old,y_old; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - m_systemCocoa->getCursorPosition(x_old,y_old); - screenToClientIntern(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - //Warp position is stored in client (window base) coordinates + m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); setCursorGrabAccum(0, 0); if (mode == GHOST_kGrabHide) { @@ -1486,7 +1473,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode } else { if (m_cursorGrab==GHOST_kGrabHide) { - //No need to set again cursor position, as it has not changed for Cocoa + m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); setWindowCursorVisibility(true); } diff --git a/intern/glew-mx/SConscript b/intern/glew-mx/SConscript index 5c70958816c..546470d020c 100644 --- a/intern/glew-mx/SConscript +++ b/intern/glew-mx/SConscript @@ -5,9 +5,8 @@ import os Import('env') sources = ['intern/glew-mx.c'] - -defs = env['BF_GL_DEFINITIONS'] - +defs = [] +defs += env['BF_GL_DEFINITIONS'] incs = [ '.', env['BF_GLEW_INC'], diff --git a/intern/glew-mx/glew-mx.h b/intern/glew-mx/glew-mx.h index 92450d67812..ed17ea4a0e6 100644 --- a/intern/glew-mx/glew-mx.h +++ b/intern/glew-mx/glew-mx.h @@ -95,8 +95,6 @@ MXContext *mxGetCurrentContext (void); void mxMakeCurrentContext(MXContext *ctx); void mxDestroyContext (MXContext *ctx); -void mxIgnoreNoVersion(int ignore); - GLenum glew_chk(GLenum error, const char *file, int line, const char *text); #ifndef NDEBUG diff --git a/intern/glew-mx/intern/glew-mx.c b/intern/glew-mx/intern/glew-mx.c index 78920670f68..6fbb1a7a2e2 100644 --- a/intern/glew-mx/intern/glew-mx.c +++ b/intern/glew-mx/intern/glew-mx.c @@ -34,8 +34,6 @@ #include <stdio.h> #include <stdlib.h> -static int ignore_version = 0; - #define CASE_CODE_RETURN_STR(code) case code: return #code; static const char *get_glew_error_enum_string(GLenum error) @@ -63,7 +61,7 @@ GLenum glew_chk(GLenum error, const char *file, int line, const char *text) const char *code = get_glew_error_enum_string(error); const char *msg = (const char *)glewGetErrorString(error); - if (error == GLEW_ERROR_NO_GL_VERSION && ignore_version) + if (error == GLEW_ERROR_NO_GL_VERSION) return GLEW_OK; #ifndef NDEBUG @@ -144,8 +142,3 @@ void mxDestroyContext(MXContext *ctx) (void)ctx; #endif } - -void mxIgnoreNoVersion(int ignore) -{ - ignore_version = ignore; -} diff --git a/intern/iksolver/intern/IK_Solver.cpp b/intern/iksolver/intern/IK_Solver.cpp index 65ea4d64ab1..eb18cde3356 100644 --- a/intern/iksolver/intern/IK_Solver.cpp +++ b/intern/iksolver/intern/IK_Solver.cpp @@ -292,6 +292,7 @@ void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float w IK_QSolver *qsolver = (IK_QSolver *)solver; IK_QSegment *qtip = (IK_QSegment *)tip; + // in case of composite segment the second segment is the tip if (qtip->Composite()) qtip = qtip->Composite(); @@ -310,6 +311,7 @@ void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[ IK_QSolver *qsolver = (IK_QSolver *)solver; IK_QSegment *qtip = (IK_QSegment *)tip; + // in case of composite segment the second segment is the tip if (qtip->Composite()) qtip = qtip->Composite(); @@ -331,6 +333,10 @@ void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float IK_QSolver *qsolver = (IK_QSolver *)solver; IK_QSegment *qtip = (IK_QSegment *)tip; + // in case of composite segment the second segment is the tip + if (qtip->Composite()) + qtip = qtip->Composite(); + MT_Vector3 qgoal(goal); MT_Vector3 qpolegoal(polegoal); diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript index c2fb95a4d95..6be6a5ed90c 100644 --- a/intern/opencolorio/SConscript +++ b/intern/opencolorio/SConscript @@ -30,7 +30,9 @@ Import('env') sources = env.Glob('*.cc') incs = '. ../guardedalloc ../../source/blender/blenlib' -defs = env['BF_GL_DEFINITIONS'] +defs = [] + +defs += env['BF_GL_DEFINITIONS'] if env['WITH_BF_OCIO']: defs.append('WITH_OCIO') diff --git a/intern/opensubdiv/CMakeLists.txt b/intern/opensubdiv/CMakeLists.txt index fceaeb94af9..a4dfe339728 100644 --- a/intern/opensubdiv/CMakeLists.txt +++ b/intern/opensubdiv/CMakeLists.txt @@ -47,7 +47,6 @@ set(SRC opensubdiv_device_context_cuda.h opensubdiv_device_context_opencl.h opensubdiv_intern.h - opensubdiv_partitioned.h ) if(WITH_SUBSURF_WERROR) diff --git a/intern/opensubdiv/SConscript b/intern/opensubdiv/SConscript index 58926c6a94a..0532bae1c29 100644 --- a/intern/opensubdiv/SConscript +++ b/intern/opensubdiv/SConscript @@ -48,16 +48,18 @@ def checkOpenSubdivHeaderDefine(header, define): return True return False -checkOpenSubdivHeaderDefine("tbbComputeController.h", 'OPENSUBDIV_HAS_TBB') -checkOpenSubdivHeaderDefine("gcdComputeController.h", 'OPENSUBDIV_HAS_GCD') -if checkOpenSubdivHeaderDefine("clComputeController.h", 'OPENSUBDIV_HAS_OPENCL'): - defs += ['OPENSUBDIV_HAS_CLEW'] - incs += ' #/extern/clew/include' -if checkOpenSubdivHeaderDefine("cudaComputeController.h", 'OPENSUBDIV_HAS_CUDA'): - defs += ['OPENSUBDIV_HAS_CUEW'] - incs += ' #/extern/cuew/include' -checkOpenSubdivHeaderDefine("glslTransformFeedbackComputeController.h", 'OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK') -checkOpenSubdivHeaderDefine("osd/glslComputeController.h", 'OPENSUBDIV_HAS_GLSL_COMPUTE') +checkOpenSubdivHeaderDefine("tbbEvaluator.h", 'OPENSUBDIV_HAS_TBB') +#if checkOpenSubdivHeaderDefine("clEvaluator.h", 'OPENSUBDIV_HAS_OPENCL'): +# defs += ['OPENSUBDIV_HAS_CLEW'] +# incs += ' #/extern/clew/include' +#if checkOpenSubdivHeaderDefine("cudaEvaluator.h", 'OPENSUBDIV_HAS_CUDA'): +# defs += ['OPENSUBDIV_HAS_CUEW'] +# incs += ' #/extern/cuew/include' +checkOpenSubdivHeaderDefine("glXFBEvaluator.h", 'OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK') +checkOpenSubdivHeaderDefine("glComputeEvaluator.h", 'OPENSUBDIV_HAS_GLSL_COMPUTE') + +if env['WITH_BF_LIBMV']: + defs += ['OPENSUBDIV_HAS_OPENMP'] # generated data files sources.extend(( diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl index fb46971bce8..e2574b5989e 100644 --- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl +++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl @@ -28,6 +28,7 @@ #extension GL_EXT_geometry_shader4 : enable #extension GL_ARB_gpu_shader5 : enable #extension GL_ARB_explicit_attrib_location : require +#extension GL_ARB_uniform_buffer_object : require struct VertexData { vec4 position; @@ -51,6 +52,10 @@ void main() { outpt.v.position = modelViewMatrix * position; outpt.v.normal = normalize(normalMatrix * normal); + /* Some compilers expects gl_Position to be written. + * It's not needed once we explicitly switch to GLSL 1.40 or above. + */ + gl_Position = outpt.v.position; } #endif /* VERTEX_SHADER */ @@ -197,15 +202,17 @@ struct LightSource { vec4 diffuse; vec4 specular; vec4 spotDirection; +#ifdef SUPPORT_COLOR_MATERIAL float constantAttenuation; float linearAttenuation; float quadraticAttenuation; float spotCutoff; float spotExponent; float spotCosCutoff; +#endif }; -uniform Lighting { +layout(std140) uniform Lighting { LightSource lightSource[MAX_LIGHTS]; int num_enabled_lights; }; @@ -215,8 +222,6 @@ uniform vec4 specular; uniform float shininess; uniform sampler2D texture_buffer; -uniform bool use_color_material; -uniform bool use_texture_2d; in block { VertexData v; @@ -236,99 +241,92 @@ void main() vec3 L_diffuse = vec3(0.0); vec3 L_specular = vec3(0.0); - if (use_color_material == false) { - /* Assume NUM_SOLID_LIGHTS directional lights. */ - for (int i = 0; i < NUM_SOLID_LIGHTS; i++) { - vec3 light_direction = lightSource[i].position.xyz; - - /* Diffuse light. */ - vec3 light_diffuse = lightSource[i].diffuse.rgb; - float diffuse_bsdf = max(dot(N, light_direction), 0.0); - L_diffuse += light_diffuse * diffuse_bsdf; - - vec4 Plight = lightSource[i].position; - vec3 l = (Plight.w == 0.0) - ? normalize(Plight.xyz) : normalize(Plight.xyz - - inpt.v.position.xyz); +#ifndef USE_COLOR_MATERIAL + /* Assume NUM_SOLID_LIGHTS directional lights. */ + for (int i = 0; i < NUM_SOLID_LIGHTS; i++) { + vec4 Plight = lightSource[i].position; +#ifdef USE_DIRECTIONAL_LIGHT + vec3 l = (Plight.w == 0.0) + ? normalize(Plight.xyz) + : normalize(inpt.v.position.xyz); +#else /* USE_DIRECTIONAL_LIGHT */ + /* TODO(sergey): We can normalize it outside of the shader. */ + vec3 l = normalize(Plight.xyz); +#endif /* USE_DIRECTIONAL_LIGHT */ + vec3 h = normalize(l + vec3(0, 0, 1)); + float d = max(0.0, dot(N, l)); + float s = pow(max(0.0, dot(N, h)), shininess); + L_diffuse += d * lightSource[i].diffuse.rgb; + L_specular += s * lightSource[i].specular.rgb; + } +#else /* USE_COLOR_MATERIAL */ + vec3 varying_position = inpt.v.position.xyz; + vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? + normalize(varying_position): vec3(0.0, 0.0, -1.0); + for (int i = 0; i < num_enabled_lights; i++) { + /* todo: this is a slow check for disabled lights */ + if (lightSource[i].specular.a == 0.0) + continue; + + float intensity = 1.0; + vec3 light_direction; + + if (lightSource[i].position.w == 0.0) { + /* directional light */ + light_direction = lightSource[i].position.xyz; + } + else { + /* point light */ + vec3 d = lightSource[i].position.xyz - varying_position; + light_direction = normalize(d); + + /* spot light cone */ + if (lightSource[i].spotCutoff < 90.0) { + float cosine = max(dot(light_direction, + -lightSource[i].spotDirection.xyz), + 0.0); + intensity = pow(cosine, lightSource[i].spotExponent); + intensity *= step(lightSource[i].spotCosCutoff, cosine); + } - /* Specular light. */ - vec3 light_specular = lightSource[i].specular.rgb; - vec3 H = normalize(l + vec3(0,0,1)); + /* falloff */ + float distance = length(d); - float specular_bsdf = pow(max(dot(N, H), 0.0), - shininess); - L_specular += light_specular * specular_bsdf; + intensity /= lightSource[i].constantAttenuation + + lightSource[i].linearAttenuation * distance + + lightSource[i].quadraticAttenuation * distance * distance; } - } - else { - vec3 varying_position = inpt.v.position.xyz; - vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? - normalize(varying_position): vec3(0.0, 0.0, -1.0); - for (int i = 0; i < num_enabled_lights; i++) { - /* todo: this is a slow check for disabled lights */ - if (lightSource[i].specular.a == 0.0) - continue; - - float intensity = 1.0; - vec3 light_direction; - - if (lightSource[i].position.w == 0.0) { - /* directional light */ - light_direction = lightSource[i].position.xyz; - } - else { - /* point light */ - vec3 d = lightSource[i].position.xyz - varying_position; - light_direction = normalize(d); - - /* spot light cone */ - if (lightSource[i].spotCutoff < 90.0) { - float cosine = max(dot(light_direction, - -lightSource[i].spotDirection.xyz), - 0.0); - intensity = pow(cosine, lightSource[i].spotExponent); - intensity *= step(lightSource[i].spotCosCutoff, cosine); - } - - /* falloff */ - float distance = length(d); - - intensity /= lightSource[i].constantAttenuation + - lightSource[i].linearAttenuation * distance + - lightSource[i].quadraticAttenuation * distance * distance; - } - /* diffuse light */ - vec3 light_diffuse = lightSource[i].diffuse.rgb; - float diffuse_bsdf = max(dot(N, light_direction), 0.0); - L_diffuse += light_diffuse*diffuse_bsdf*intensity; + /* diffuse light */ + vec3 light_diffuse = lightSource[i].diffuse.rgb; + float diffuse_bsdf = max(dot(N, light_direction), 0.0); + L_diffuse += light_diffuse*diffuse_bsdf*intensity; - /* specular light */ - vec3 light_specular = lightSource[i].specular.rgb; - vec3 H = normalize(light_direction - V); + /* specular light */ + vec3 light_specular = lightSource[i].specular.rgb; + vec3 H = normalize(light_direction - V); - float specular_bsdf = pow(max(dot(N, H), 0.0), - gl_FrontMaterial.shininess); - L_specular += light_specular*specular_bsdf * intensity; - } + float specular_bsdf = pow(max(dot(N, H), 0.0), + gl_FrontMaterial.shininess); + L_specular += light_specular*specular_bsdf * intensity; } +#endif /* USE_COLOR_MATERIAL */ /* Compute diffuse color. */ - float alpha; - if (use_texture_2d) { - L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb; - } - else { - L_diffuse *= diffuse.rgb; - } - alpha = diffuse.a; +#ifdef USE_TEXTURE_2D + L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb; +#else + L_diffuse *= diffuse.rgb; +#endif /* Sum lighting. */ - vec3 L = /*gl_FrontLightModelProduct.sceneColor.rgb +*/ L_diffuse; - L += L_specular * specular.rgb; + vec3 L = L_diffuse; + if (shininess != 0) { + L += L_specular * specular.rgb; + } /* Write out fragment color. */ - gl_FragColor = vec4(L, alpha); + gl_FragColor = vec4(L, diffuse.a); #endif } diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc index e3bc5891c45..66598948daf 100644 --- a/intern/opensubdiv/opensubdiv_capi.cc +++ b/intern/opensubdiv/opensubdiv_capi.cc @@ -30,6 +30,7 @@ # include "iso646.h" #endif +#include <stdlib.h> #include <GL/glew.h> #include <opensubdiv/osd/glMesh.h> @@ -68,7 +69,6 @@ #include <opensubdiv/far/stencilTable.h> #include "opensubdiv_intern.h" -#include "opensubdiv_partitioned.h" #include "MEM_guardedalloc.h" @@ -80,22 +80,22 @@ using OpenSubdiv::Osd::MeshBitset; using OpenSubdiv::Far::StencilTable; using OpenSubdiv::Osd::GLPatchTable; -using OpenSubdiv::Osd::PartitionedMesh; +using OpenSubdiv::Osd::Mesh; /* CPU backend */ using OpenSubdiv::Osd::CpuGLVertexBuffer; using OpenSubdiv::Osd::CpuEvaluator; -typedef PartitionedMesh<CpuGLVertexBuffer, - StencilTable, - CpuEvaluator, - GLPatchTable> OsdCpuMesh; +typedef Mesh<CpuGLVertexBuffer, + StencilTable, + CpuEvaluator, + GLPatchTable> OsdCpuMesh; #ifdef OPENSUBDIV_HAS_OPENMP using OpenSubdiv::Osd::OmpEvaluator; -typedef PartitionedMesh<CpuGLVertexBuffer, - StencilTable, - OmpEvaluator, - GLPatchTable> OsdOmpMesh; +typedef Mesh<CpuGLVertexBuffer, + StencilTable, + OmpEvaluator, + GLPatchTable> OsdOmpMesh; #endif /* OPENSUBDIV_HAS_OPENMP */ #ifdef OPENSUBDIV_HAS_OPENCL @@ -103,11 +103,11 @@ using OpenSubdiv::Osd::CLEvaluator; using OpenSubdiv::Osd::CLGLVertexBuffer; using OpenSubdiv::Osd::CLStencilTable; /* TODO(sergey): Use CLDeviceCOntext similar to OSD examples? */ -typedef PartitionedMesh<CLGLVertexBuffer, - CLStencilTable, - CLEvaluator, - GLPatchTable, - CLDeviceContext> OsdCLMesh; +typedef Mesh<CLGLVertexBuffer, + CLStencilTable, + CLEvaluator, + GLPatchTable, + CLDeviceContext> OsdCLMesh; static CLDeviceContext g_clDeviceContext; #endif /* OPENSUBDIV_HAS_OPENCL */ @@ -115,10 +115,10 @@ static CLDeviceContext g_clDeviceContext; using OpenSubdiv::Osd::CudaEvaluator; using OpenSubdiv::Osd::CudaGLVertexBuffer; using OpenSubdiv::Osd::CudaStencilTable; -typedef PartitionedMesh<CudaGLVertexBuffer, - CudaStencilTable, - CudaEvaluator, - GLPatchTable> OsdCudaMesh; +typedef Mesh<CudaGLVertexBuffer, + CudaStencilTable, + CudaEvaluator, + GLPatchTable> OsdCudaMesh; static CudaDeviceContext g_cudaDeviceContext; #endif /* OPENSUBDIV_HAS_CUDA */ @@ -126,20 +126,20 @@ static CudaDeviceContext g_cudaDeviceContext; using OpenSubdiv::Osd::GLXFBEvaluator; using OpenSubdiv::Osd::GLStencilTableTBO; using OpenSubdiv::Osd::GLVertexBuffer; -typedef PartitionedMesh<GLVertexBuffer, - GLStencilTableTBO, - GLXFBEvaluator, - GLPatchTable> OsdGLSLTransformFeedbackMesh; +typedef Mesh<GLVertexBuffer, + GLStencilTableTBO, + GLXFBEvaluator, + GLPatchTable> OsdGLSLTransformFeedbackMesh; #endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */ #ifdef OPENSUBDIV_HAS_GLSL_COMPUTE using OpenSubdiv::Osd::GLComputeEvaluator; using OpenSubdiv::Osd::GLStencilTableSSBO; using OpenSubdiv::Osd::GLVertexBuffer; -typedef PartitionedMesh<GLVertexBuffer, - GLStencilTableSSBO, - GLComputeEvaluator, - GLPatchTable> OsdGLSLComputeMesh; +typedef Mesh<GLVertexBuffer, + GLStencilTableSSBO, + GLComputeEvaluator, + GLPatchTable> OsdGLSLComputeMesh; #endif struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner( @@ -156,14 +156,12 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner( */ bits.set(OpenSubdiv::Osd::MeshAdaptive, 0); bits.set(OpenSubdiv::Osd::MeshUseSingleCreasePatch, 0); - bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 0); + bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 1); bits.set(OpenSubdiv::Osd::MeshFVarData, 1); bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1); - // bits.set(Osd::MeshEndCapGregoryBasis, 1); - // bits.set(Osd::MeshEndCapLegacyGregory, 1); - const int num_vertex_elements = 6; - const int num_varying_elements = 0; + const int num_vertex_elements = 3; + const int num_varying_elements = 3; GLMeshInterface *mesh = NULL; TopologyRefiner *refiner = (TopologyRefiner*)topology_refiner; @@ -297,7 +295,29 @@ const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefine int openSubdiv_supportGPUDisplay(void) { - return GL_EXT_geometry_shader4 && - GL_ARB_gpu_shader5 && - glProgramParameteriEXT; + { + /* Currently Intel GPUs has hard time working on Windows. + * + * For until we've got access to a hardware which demonstrates + * the issue we disable OpenSubdiv on Intel GPUs. + */ + static bool vendor_checked = false; + static bool is_intel = false; + if (!vendor_checked) { + vendor_checked = true; + const char *vendor = (const char *)glGetString(GL_VENDOR); + if (vendor != NULL && strstr(vendor, "Intel")) { + if(getenv("OPENSUBDIV_ALLOW_INTEL") == NULL) { + is_intel = true; + } + } + } + if (is_intel) { + return false; + } + } + + return GLEW_EXT_geometry_shader4 && + GLEW_ARB_gpu_shader5 && + GLEW_ARB_uniform_buffer_object; } diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h index c86e739f12b..8010c39647d 100644 --- a/intern/opensubdiv/opensubdiv_capi.h +++ b/intern/opensubdiv/opensubdiv_capi.h @@ -85,7 +85,7 @@ const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefine OpenSubdiv_GLMesh *gl_mesh); /* ** Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs ** */ -void openSubdiv_osdGLDisplayInit(void); +bool openSubdiv_osdGLDisplayInit(void); void openSubdiv_osdGLDisplayDeinit(void); /* ** Evaluator API ** */ @@ -132,15 +132,16 @@ void openSubdiv_evaluateVarying(OpenSubdiv_EvaluatorDescr *evaluator_descr, void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, int active_uv_index); -/* Draw patches which corresponds to a given partition. */ +/* Draw specified patches. */ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, int fill_quads, - int start_partition, - int num_partitions); + int start_patch, + int num_patches); /* ** Utility functions ** */ int openSubdiv_supportGPUDisplay(void); int openSubdiv_getAvailableEvaluators(void); +void openSubdiv_init(void); void openSubdiv_cleanup(void); #ifdef __cplusplus diff --git a/intern/opensubdiv/opensubdiv_converter.cc b/intern/opensubdiv/opensubdiv_converter.cc index 119a7bf9340..3fadde68d32 100644 --- a/intern/opensubdiv/opensubdiv_converter.cc +++ b/intern/opensubdiv/opensubdiv_converter.cc @@ -37,6 +37,21 @@ #include <stack> +#ifdef OPENSUBDIV_ORIENT_TOPOLOGY +namespace { + +inline void reverse_face_verts(int *face_verts, int num_verts) +{ + int last_vert = face_verts[num_verts - 1]; + for (int i = num_verts - 1; i > 0; --i) { + face_verts[i] = face_verts[i - 1]; + } + face_verts[0] = last_vert; +} + +} /* namespace */ +#endif /* OPENSUBDIV_ORIENT_TOPOLOGY */ + namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { namespace Far { @@ -49,22 +64,77 @@ inline int findInArray(T array, int value) return (int)(std::find(array.begin(), array.end(), value) - array.begin()); } -} /* namespace */ +#ifdef OPENSUBDIV_ORIENT_TOPOLOGY +inline int get_loop_winding(int vert0_of_face, int vert1_of_face) +{ + int delta_face = vert1_of_face - vert0_of_face; + if (abs(delta_face) != 1) { + if (delta_face > 0) { + delta_face = -1; + } + else { + delta_face = 1; + } + } + return delta_face; +} -struct StackElem { - StackElem(int face_start, - int edge_start, - int face_vert_start, - bool append_start_edge = true) - : face_start(face_start), - edge_start(edge_start), - face_vert_start(face_vert_start), - append_start_edge(append_start_edge){} - int face_start; - int edge_start; - int face_vert_start; - bool append_start_edge; -}; +inline void reverse_face_loops(IndexArray face_verts, IndexArray face_edges) +{ + for (int i = 0; i < face_verts.size() / 2; ++i) { + int j = face_verts.size() - i - 1; + if (i != j) { + std::swap(face_verts[i], face_verts[j]); + std::swap(face_edges[i], face_edges[j]); + } + } + reverse_face_verts(&face_verts[0], face_verts.size()); +} + +inline void check_oriented_vert_connectivity(const int num_vert_edges, + const int num_vert_faces, + const int *vert_edges, + const int *vert_faces, + const int *dst_vert_edges, + const int *dst_vert_faces) +{ +# ifndef NDEBUG + for (int i = 0; i < num_vert_faces; ++i) { + bool found = false; + for (int j = 0; j < num_vert_faces; ++j) { + if (vert_faces[i] == dst_vert_faces[j]) { + found = true; + break; + } + } + if (!found) { + assert(!"vert-faces connectivity ruined"); + } + } + for (int i = 0; i < num_vert_edges; ++i) { + bool found = false; + for (int j = 0; j < num_vert_edges; ++j) { + if (vert_edges[i] == dst_vert_edges[j]) { + found = true; + break; + } + } + if (!found) { + assert(!"vert-edges connectivity ruined"); + } + } +# else + (void)num_vert_edges; + (void)num_vert_faces; + (void)vert_edges; + (void)vert_faces; + (void)dst_vert_edges; + (void)dst_vert_faces; +# endif +} +#endif + +} /* namespace */ template <> inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::resizeComponentTopology( @@ -121,9 +191,73 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog IndexArray dst_edge_faces = getBaseEdgeFaces(refiner, edge); conv.get_edge_faces(&conv, edge, &dst_edge_faces[0]); } +#ifdef OPENSUBDIV_ORIENT_TOPOLOGY + /* Make face normals consistent. */ + bool *face_used = new bool[num_faces]; + memset(face_used, 0, sizeof(bool) * num_faces); + std::stack<int> traverse_stack; + int face_start = 0, num_traversed_faces = 0; + /* Traverse all islands. */ + while (num_traversed_faces != num_faces) { + /* Find first face of any untraversed islands. */ + while (face_used[face_start]) { + ++face_start; + } + /* Add first face to the stack. */ + traverse_stack.push(face_start); + face_used[face_start] = true; + /* Go over whole connected component. */ + while (!traverse_stack.empty()) { + int face = traverse_stack.top(); + traverse_stack.pop(); + IndexArray face_edges = getBaseFaceEdges(refiner, face); + ConstIndexArray face_verts = getBaseFaceVertices(refiner, face); + for (int edge_index = 0; edge_index < face_edges.size(); ++edge_index) { + const int edge = face_edges[edge_index]; + ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge); + if (edge_faces.size() != 2) { + /* Can't make consistent normals for non-manifolds. */ + continue; + } + ConstIndexArray edge_verts = getBaseEdgeVertices(refiner, edge); + /* Get winding of the reference face. */ + int vert0_of_face = findInArray(face_verts, edge_verts[0]), + vert1_of_face = findInArray(face_verts, edge_verts[1]); + int delta_face = get_loop_winding(vert0_of_face, vert1_of_face); + for (int edge_face = 0; edge_face < edge_faces.size(); ++edge_face) { + int other_face = edge_faces[edge_face]; + /* Never re-traverse faces, only move forward. */ + if (face_used[other_face]) { + continue; + } + IndexArray other_face_verts = getBaseFaceVertices(refiner, + other_face); + int vert0_of_other_face = findInArray(other_face_verts, + edge_verts[0]), + vert1_of_other_face = findInArray(other_face_verts, + edge_verts[1]); + int delta_other_face = get_loop_winding(vert0_of_other_face, + vert1_of_other_face); + if (delta_face * delta_other_face > 0) { + IndexArray other_face_verts = getBaseFaceVertices(refiner, + other_face), + other_face_edges = getBaseFaceEdges(refiner, + other_face); + reverse_face_loops(other_face_verts, + other_face_edges); + } + traverse_stack.push(other_face); + face_used[other_face] = true; + } + } + ++num_traversed_faces; + } + } +#endif /* OPENSUBDIV_ORIENT_TOPOLOGY */ /* Vertex relations */ const int num_verts = conv.get_num_verts(&conv); for (int vert = 0; vert < num_verts; ++vert) { + /* Vert-Faces */ IndexArray dst_vert_faces = getBaseVertexFaces(refiner, vert); int num_vert_faces = conv.get_num_vert_faces(&conv, vert); @@ -135,56 +269,101 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog int *vert_edges = new int[num_vert_edges]; conv.get_vert_edges(&conv, vert, vert_edges); #ifdef OPENSUBDIV_ORIENT_TOPOLOGY - /* Order vertex edges and faces in a CCW order. */ - /* TODO(sergey): Look into possible optimizations here. */ - bool *face_used = new bool[num_faces]; + /* ** Order vertex edges and faces in a CCW order. ** */ memset(face_used, 0, sizeof(bool) * num_faces); - std::stack<StackElem> stack; + /* Number of edges and faces added to the ordered array. */ int edge_count_ordered = 0, face_count_ordered = 0; - if (num_vert_edges == num_vert_faces) { - /* Manifold vertex, start with any face and perform traversal. */ - int face_start = vert_faces[0]; - int face_vert_start = findInArray(getBaseFaceVertices(refiner, face_start), vert); - int edge_start = getBaseFaceEdges(refiner, face_start)[face_vert_start]; - stack.push(StackElem(face_start, edge_start, face_vert_start)); + /* Add loose edges straight into the edges array. */ + bool has_fan_connections = false; + for (int i = 0; i < num_vert_edges; ++i) { + IndexArray edge_faces = getBaseEdgeFaces(refiner, vert_edges[i]); + if (edge_faces.size() == 0) { + dst_vert_edges[edge_count_ordered++] = vert_edges[i]; + } + else if (edge_faces.size() > 2) { + has_fan_connections = true; + } } - else { - /* ** Non-manifold vertex. Special handle here. ** */ - /* Add all loose edges adjacent to the vertex. */ - for (int i = 0; i < num_vert_edges; ++i) { - IndexArray edge_faces = getBaseEdgeFaces(refiner, vert_edges[i]); - if (edge_faces.size() == 0) { - /* Can't really orient loose edges, just add then straight - * to the vert-edges array. - */ - dst_vert_edges[edge_count_ordered++] = vert_edges[i]; + if (has_fan_connections) { + /* OpenSubdiv currently doesn't give us clues how to handle + * fan face connections. and since handling such connections + * complicates the loop below we simply don't do special + * orientation for them. + */ + memcpy(&dst_vert_edges[0], vert_edges, sizeof(int) * num_vert_edges); + memcpy(&dst_vert_faces[0], vert_faces, sizeof(int) * num_vert_faces); + delete [] vert_edges; + delete [] vert_faces; + continue; + } + /* Perform at max numbder of vert-edges iteration and try to avoid + * deadlock here for malformed mesh. + */ + for (int global_iter = 0; global_iter < num_vert_edges; ++global_iter) { + /* Numbr of edges and faces which are still to be ordered. */ + int num_vert_edges_remained = num_vert_edges - edge_count_ordered, + num_vert_faces_remained = num_vert_faces - face_count_ordered; + if (num_vert_edges_remained == 0 && num_vert_faces_remained == 0) { + /* All done, nothing to do anymore. */ + break; + } + /* Face, edge and face-vertex inndex to start traversal from. */ + int face_start = -1, edge_start = -1, face_vert_start = -1; + if (num_vert_edges_remained == num_vert_faces_remained) { + /* Vertex is eitehr complete manifold or is connected to seevral + * manifold islands (hourglass-like configuration), can pick up + * random edge unused and start from it. + */ + /* TODO(sergey): Start from previous edge from which traversal + * began at previous iteration. + */ + for (int i = 0; i < num_vert_edges; ++i) { + face_start = vert_faces[i]; + if (!face_used[face_start]) { + ConstIndexArray + face_verts = getBaseFaceVertices(refiner, face_start), + face_edges = getBaseFaceEdges(refiner, face_start); + face_vert_start = findInArray(face_verts, vert); + edge_start = face_edges[face_vert_start]; + break; + } } - else if (edge_faces.size() == 1) { - int edge_start = vert_edges[i]; - int face_start = edge_faces[0]; - int face_vert_start = findInArray(getBaseFaceVertices(refiner, face_start), vert); - if (edge_start == (getBaseFaceEdges(refiner, face_start)[face_vert_start])) { - stack.push(StackElem(face_start, edge_start, face_vert_start)); - face_used[face_start] = true; + } + else { + /* Special handle of non-manifold vertex. */ + for (int i = 0; i < num_vert_edges; ++i) { + bool start_found = false; + edge_start = vert_edges[i]; + IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_start); + if (edge_faces.size() == 1) { + face_start = edge_faces[0]; + if (!face_used[face_start]) { + ConstIndexArray + face_verts = getBaseFaceVertices(refiner, face_start), + face_edges = getBaseFaceEdges(refiner, face_start); + face_vert_start = findInArray(face_verts, vert); + if (edge_start == face_edges[face_vert_start]) { + start_found = true; + break; + } + } } + if (start_found) { + break; + } + /* Reset indices for sanity check below. */ + face_start = edge_start = face_vert_start = -1; } } - } - while (!stack.empty()) { - StackElem& top = stack.top(); - int edge_start = top.edge_start; - int face_start = top.face_start; - int face_vert_start = top.face_vert_start; - bool append_start_edge = top.append_start_edge; - stack.pop(); - Index edge_first = edge_start; - + /* Sanity check. */ + assert(face_start != -1 && + edge_start != -1 && + face_vert_start != -1); + /* Traverse faces starting from the current one. */ + int edge_first = edge_start; dst_vert_faces[face_count_ordered++] = face_start; - if (append_start_edge) { - dst_vert_edges[edge_count_ordered++] = edge_start; - } + dst_vert_edges[edge_count_ordered++] = edge_start; face_used[face_start] = true; - while (edge_count_ordered < num_vert_edges) { IndexArray face_verts = getBaseFaceVertices(refiner, face_start); IndexArray face_edges = getBaseFaceEdges(refiner, face_start); @@ -192,24 +371,9 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog int face_edge_next = (face_edge_start > 0) ? (face_edge_start - 1) : (face_verts.size() - 1); Index edge_next = face_edges[face_edge_next]; if (edge_next == edge_first) { - /* TODO(sergey): Find more generic solution so non-manifold - * edges combined with some manifold adjacent geometry is - * handled correct. + /* Multiple manifolds found, stop for now and handle rest + * in the next iteration. */ - if (num_vert_edges == num_vert_faces && - edge_count_ordered != num_vert_edges) - { - IndexArray edge_faces = getBaseEdgeFaces(refiner, edge_next); - for (int i = 0; i < num_vert_faces; ++i) { - int face_start = edge_faces[i]; - if (!face_used[face_start]) { - int edge_start = edge_next; - int face_vert_start = findInArray(getBaseFaceVertices(refiner, face_start), vert); - stack.push(StackElem(face_start, edge_start, face_vert_start, false)); - break; - } - } - } break; } dst_vert_edges[edge_count_ordered++] = edge_next; @@ -221,16 +385,6 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog break; } else if (edge_faces.size() != 2) { - for (int i = 0; i < edge_faces.size(); ++i) { - if (edge_faces[i] != face_start) { - int face_start = edge_faces[i]; - if (!face_used[face_start]) { - int edge_start = edge_next; - int face_vert_start = findInArray(getBaseFaceVertices(refiner, face_start), vert); - stack.push(StackElem(face_start, edge_start, face_vert_start, false)); - } - } - } break; } assert(edge_faces.size() == 2); @@ -242,45 +396,36 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTopolog edge_start = edge_next; } } - delete [] face_used; - /* Verify ordering doesn't ruin connectivity information. */ assert(face_count_ordered == num_vert_faces); assert(edge_count_ordered == num_vert_edges); -#ifndef NDEBUG - for (int i = 0; i < num_vert_faces; ++i) { - bool found = false; - for (int j = 0; j < num_vert_faces; ++j) { - if (vert_faces[i] == dst_vert_faces[j]) { - found = true; - break; - } - } - if (!found) { - assert(!"vert-faces connectivity ruined"); - } - } - for (int i = 0; i < num_vert_edges; ++i) { - bool found = false; - for (int j = 0; j < num_vert_edges; ++j) { - if (vert_edges[i] == dst_vert_edges[j]) { - found = true; - break; - } - } - if (!found) { - assert(!"vert-edges connectivity ruined"); - } + check_oriented_vert_connectivity(num_vert_edges, + num_vert_faces, + vert_edges, + vert_faces, + &dst_vert_edges[0], + &dst_vert_faces[0]); + /* For the release builds we're failing mesh construction so instead + * of nasty bugs the unsupported mesh will simply disappear from the + * viewport. + */ + if (face_count_ordered != num_vert_faces || + edge_count_ordered != num_vert_edges) + { + delete [] vert_edges; + delete [] vert_faces; + return false; } -#endif #else /* OPENSUBDIV_ORIENT_TOPOLOGY */ memcpy(&dst_vert_edges[0], vert_edges, sizeof(int) * num_vert_edges); memcpy(&dst_vert_faces[0], vert_faces, sizeof(int) * num_vert_faces); #endif /* OPENSUBDIV_ORIENT_TOPOLOGY */ - delete [] vert_edges; delete [] vert_faces; } +#ifdef OPENSUBDIV_ORIENT_TOPOLOGY + delete [] face_used; +#endif populateBaseLocalIndices(refiner); return true; }; @@ -306,21 +451,31 @@ inline bool TopologyRefinerFactory<OpenSubdiv_Converter>::assignComponentTags( setBaseEdgeSharpness(refiner, edge, sharpness); } -#if 0 - /* Non-manifold vertices can't be always smooth. - * I.e. when there's loose edge adjacent to the vertex - * opensubdiv expects vertices to be sharp. But this needs - * some further investigation. + /* OpenSubdiv expects non-manifold vertices to be sharp but at the + * time it handles correct cases when vertex is a corner of plane. + * Currently mark verts which are adjacent to a loose edge as sharp, + * but this decision needs some more investigation. */ int num_vert = conv.get_num_verts(&conv); for (int vert = 0; vert < num_vert; ++vert) { - IndexArray vert_faces = getBaseVertexFaces(refiner, vert), - vert_edges = getBaseVertexEdges(refiner, vert); - if (vert_faces.size() != vert_edges.size()) { - setBaseVertexSharpness(refiner, vert, Crease::SHARPNESS_INFINITE); + ConstIndexArray vert_edges = getBaseVertexEdges(refiner, vert); + for (int edge_index = 0; edge_index < vert_edges.size(); ++edge_index) { + int edge = vert_edges[edge_index]; + ConstIndexArray edge_faces = getBaseEdgeFaces(refiner, edge); + if (edge_faces.size() == 0) { + setBaseVertexSharpness(refiner, vert, Crease::SHARPNESS_INFINITE); + break; + } + } + if (vert_edges.size() == 2) { + int edge0 = vert_edges[0], + edge1 = vert_edges[1]; + float sharpness0 = conv.get_edge_sharpness(&conv, edge0), + sharpness1 = conv.get_edge_sharpness(&conv, edge1); + float sharpness = std::min(sharpness0, sharpness1); + setBaseVertexSharpness(refiner, vert, sharpness); } } -#endif return true; } @@ -427,6 +582,17 @@ int openSubdiv_topologyRefinerGetNumFaces( return base_level.GetNumFaces(); } +int openSubdiv_topologyRefinerGetNumFaceVerts( + const OpenSubdiv_TopologyRefinerDescr *topology_refiner, + int face) +{ + using OpenSubdiv::Far::TopologyLevel; + using OpenSubdiv::Far::TopologyRefiner; + const TopologyRefiner *refiner = (const TopologyRefiner *)topology_refiner; + const TopologyLevel &base_level = refiner->GetLevel(0); + return base_level.GetFaceVertices(face).size(); +} + int openSubdiv_topologyRefnerCompareConverter( const OpenSubdiv_TopologyRefinerDescr *topology_refiner, OpenSubdiv_Converter *converter) @@ -473,11 +639,29 @@ int openSubdiv_topologyRefnerCompareConverter( } conv_face_verts.resize(face_verts.size()); converter->get_face_verts(converter, face, &conv_face_verts[0]); + bool direct_match = true; for (int i = 0; i < face_verts.size(); ++i) { if (conv_face_verts[i] != face_verts[i]) { - return false; + direct_match = false; + break; } } + if (!direct_match) { + /* If face didn't match in direct direction we also test if it + * matches in reversed direction. This is because conversion might + * reverse loops to make normals consistent. + */ +#ifdef OPENSUBDIV_ORIENT_TOPOLOGY + reverse_face_verts(&conv_face_verts[0], conv_face_verts.size()); + for (int i = 0; i < face_verts.size(); ++i) { + if (conv_face_verts[i] != face_verts[i]) { + return false; + } + } +#else + return false; +#endif + } } /* Compare sharpness. */ for (int edge = 0; edge < num_edges; ++edge) { diff --git a/intern/opensubdiv/opensubdiv_converter_capi.h b/intern/opensubdiv/opensubdiv_converter_capi.h index 7c96d3d8b96..ac1e8301a42 100644 --- a/intern/opensubdiv/opensubdiv_converter_capi.h +++ b/intern/opensubdiv/opensubdiv_converter_capi.h @@ -94,7 +94,7 @@ void openSubdiv_deleteTopologyRefinerDescr( OpenSubdiv_TopologyRefinerDescr *topology_refiner); /* TODO(sergey): Those calls are not strictly related on conversion. - * needs some dedicated fiel perhaps. + * needs some dedicated file perhaps. */ int openSubdiv_topologyRefinerGetSubdivLevel( @@ -109,6 +109,10 @@ int openSubdiv_topologyRefinerGetNumEdges( int openSubdiv_topologyRefinerGetNumFaces( const OpenSubdiv_TopologyRefinerDescr *topology_refiner); +int openSubdiv_topologyRefinerGetNumFaceVerts( + const OpenSubdiv_TopologyRefinerDescr *topology_refiner, + int face); + int openSubdiv_topologyRefnerCompareConverter( const OpenSubdiv_TopologyRefinerDescr *topology_refiner, OpenSubdiv_Converter *converter); diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.cc b/intern/opensubdiv/opensubdiv_evaluator_capi.cc index b8527fda4e5..0da6b9daba8 100644 --- a/intern/opensubdiv/opensubdiv_evaluator_capi.cc +++ b/intern/opensubdiv/opensubdiv_evaluator_capi.cc @@ -351,15 +351,11 @@ OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr( const StencilTable *varying_stencils = NULL; int num_total_verts = 0; - /* Apply adaptive refinement to the mesh so that we can use the + /* Apply uniform refinement to the mesh so that we can use the * limit evaluation API features. - * - * TODO(sergey): Once OpenSubdiv supports uniform meshes in limit - * evlauation we need to switch to uniform here, which will match - * original Blender subsurf. */ - TopologyRefiner::AdaptiveOptions options(subsurf_level); - refiner->RefineAdaptive(options); + TopologyRefiner::UniformOptions options(subsurf_level); + refiner->RefineUniform(options); /* Generate stencil table to update the bi-cubic patches control * vertices after they have been re-posed (both for vertex & varying @@ -367,7 +363,7 @@ OpenSubdiv_EvaluatorDescr *openSubdiv_createEvaluatorDescr( */ StencilTableFactory::Options soptions; soptions.generateOffsets = true; - soptions.generateIntermediateLevels = true; + soptions.generateIntermediateLevels = false; vertex_stencils = StencilTableFactory::Create(*refiner, soptions); diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc index d46211f3668..31996a1bab8 100644 --- a/intern/opensubdiv/opensubdiv_gpu_capi.cc +++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc @@ -47,11 +47,7 @@ #include <opensubdiv/osd/cpuGLVertexBuffer.h> #include <opensubdiv/osd/cpuEvaluator.h> -#include "opensubdiv_partitioned.h" - -//using OpenSubdiv::FarPatchTables; using OpenSubdiv::Osd::GLMeshInterface; -//sing OpenSubdiv::PartitionedGLMeshInterface; extern "C" char datatoc_gpu_shader_opensubd_display_glsl[]; @@ -62,19 +58,19 @@ typedef struct Light { float diffuse[4]; float specular[4]; float spot_direction[4]; +#ifdef SUPPORT_COLOR_MATERIAL float constant_attenuation; float linear_attenuation; float quadratic_attenuation; float spot_cutoff; float spot_exponent; float spot_cos_cutoff; - float pad[2]; +#endif } Light; typedef struct Lighting { Light lights[MAX_LIGHTS]; int num_enabled; - int pad[3]; } Lighting; typedef struct Transform { @@ -86,8 +82,10 @@ typedef struct Transform { static bool g_use_osd_glsl = false; static int g_active_uv_index = -1; -static GLuint g_flat_fill_program = 0; -static GLuint g_smooth_fill_program = 0; +static GLuint g_flat_fill_solid_program = 0; +static GLuint g_flat_fill_texture2d_program = 0; +static GLuint g_smooth_fill_solid_program = 0; +static GLuint g_smooth_fill_texture2d_program = 0; static GLuint g_wireframe_program = 0; static GLuint g_lighting_ub = 0; @@ -216,7 +214,7 @@ GLuint compileShader(GLenum shaderType, fprintf(stderr, "Section: %s\n", sdefine); fprintf(stderr, "Defines: %s\n", define); fprintf(stderr, "Source: %s\n", sources[2]); - exit(1); + return 0; } return shader; @@ -227,12 +225,21 @@ GLuint linkProgram(const char *define) GLuint vertexShader = compileShader(GL_VERTEX_SHADER, "VERTEX_SHADER", define); + if (vertexShader == 0) { + return 0; + } GLuint geometryShader = compileShader(GL_GEOMETRY_SHADER, "GEOMETRY_SHADER", define); + if (geometryShader == 0) { + return 0; + } GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, "FRAGMENT_SHADER", define); + if (fragmentShader == 0) { + return 0; + } GLuint program = glCreateProgram(); @@ -281,7 +288,8 @@ GLuint linkProgram(const char *define) glGetProgramInfoLog(program, sizeof(emsg), 0, emsg); fprintf(stderr, "Error linking GLSL program : %s\n", emsg); fprintf(stderr, "Defines: %s\n", define); - exit(1); + glDeleteProgram(program); + return 0; } glUniformBlockBinding(program, @@ -299,7 +307,7 @@ GLuint linkProgram(const char *define) return program; } -void bindProgram(PartitionedGLMeshInterface * /*mesh*/, +void bindProgram(GLMeshInterface * /*mesh*/, int program) { glUseProgram(program); @@ -324,15 +332,8 @@ void bindProgram(PartitionedGLMeshInterface * /*mesh*/, glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub); /* Color */ - GLboolean use_lighting, use_color_material, use_texture_2d; + GLboolean use_lighting; glGetBooleanv(GL_LIGHTING, &use_lighting); - glGetBooleanv(GL_COLOR_MATERIAL, &use_color_material); - glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); - - glUniform1i(glGetUniformLocation(program, "use_color_material"), - use_color_material); - glUniform1i(glGetUniformLocation(program, "use_texture_2d"), - use_texture_2d); if (use_lighting) { float color[4]; @@ -372,12 +373,15 @@ void bindProgram(PartitionedGLMeshInterface * /*mesh*/, } /* namespace */ -void openSubdiv_osdGLDisplayInit(void) +bool openSubdiv_osdGLDisplayInit(void) { static bool need_init = true; + static bool init_success = false; if (need_init) { - g_flat_fill_program = linkProgram("#define FLAT_SHADING\n"); - g_smooth_fill_program = linkProgram("#define SMOOTH_SHADING\n"); + g_flat_fill_solid_program = linkProgram("#define FLAT_SHADING\n"); + g_flat_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define FLAT_SHADING\n"); + g_smooth_fill_solid_program = linkProgram("#define SMOOTH_SHADING\n"); + g_smooth_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define SMOOTH_SHADING\n"); g_wireframe_program = linkProgram("#define WIREFRAME\n"); glGenBuffers(1, &g_lighting_ub); @@ -386,7 +390,13 @@ void openSubdiv_osdGLDisplayInit(void) sizeof(g_lighting_data), NULL, GL_STATIC_DRAW); need_init = false; + init_success = g_flat_fill_solid_program != 0 && + g_flat_fill_texture2d_program != 0 && + g_smooth_fill_solid_program != 0 && + g_smooth_fill_texture2d_program != 0 && + g_wireframe_program; } + return init_success; } void openSubdiv_osdGLDisplayDeinit(void) @@ -394,11 +404,17 @@ void openSubdiv_osdGLDisplayDeinit(void) if (g_lighting_ub != 0) { glDeleteBuffers(1, &g_lighting_ub); } - if (g_flat_fill_program) { - glDeleteProgram(g_flat_fill_program); + if (g_flat_fill_solid_program) { + glDeleteProgram(g_flat_fill_solid_program); + } + if (g_flat_fill_texture2d_program) { + glDeleteProgram(g_flat_fill_texture2d_program); } - if (g_smooth_fill_program) { - glDeleteProgram(g_flat_fill_program); + if (g_smooth_fill_solid_program) { + glDeleteProgram(g_flat_fill_solid_program); + } + if (g_smooth_fill_texture2d_program) { + glDeleteProgram(g_smooth_fill_texture2d_program); } if (g_wireframe_program) { glDeleteProgram(g_wireframe_program); @@ -444,6 +460,7 @@ void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, g_lighting_data.lights[i].spot_direction); +#ifdef SUPPORT_COLOR_MATERIAL glGetLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &g_lighting_data.lights[i].constant_attenuation); @@ -461,10 +478,11 @@ void openSubdiv_osdGLMeshDisplayPrepare(int use_osd_glsl, &g_lighting_data.lights[i].spot_exponent); g_lighting_data.lights[i].spot_cos_cutoff = cos(g_lighting_data.lights[i].spot_cutoff); +#endif } } -static GLuint preapre_patchDraw(PartitionedGLMeshInterface *mesh, +static GLuint preapre_patchDraw(GLMeshInterface *mesh, bool fill_quads) { GLint program = 0; @@ -505,12 +523,26 @@ static GLuint preapre_patchDraw(PartitionedGLMeshInterface *mesh, return program; } - program = g_smooth_fill_program; if (fill_quads) { int model; + GLboolean use_texture_2d; glGetIntegerv(GL_SHADE_MODEL, &model); + glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d); if (model == GL_FLAT) { - program = g_flat_fill_program; + if (use_texture_2d) { + program = g_flat_fill_texture2d_program; + } + else { + program = g_flat_fill_solid_program; + } + } + else { + if (use_texture_2d) { + program = g_smooth_fill_texture2d_program; + } + else { + program = g_smooth_fill_solid_program; + } } } else { @@ -528,13 +560,11 @@ static void perform_drawElements(GLuint program, int num_elements, int start_element) { - int mode = GL_QUADS; if (program) { glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), patch_index); } - mode = GL_LINES_ADJACENCY; - glDrawElements(mode, + glDrawElements(GL_LINES_ADJACENCY, num_elements, GL_UNSIGNED_INT, (void *)(start_element * sizeof(unsigned int))); @@ -558,48 +588,43 @@ static void finish_patchDraw(bool fill_quads) } } -#if 0 -static void draw_partition_patches_range(PartitionedGLMeshInterface *mesh, +static void draw_partition_patches_range(GLMeshInterface *mesh, GLuint program, - int start_partition, - int num_partitions) + int start_patch, + int num_patches) { - /* Glue patches from all partitions in the range together. */ - int patch_index = -1, start_element = -1, num_elements = 0; - for (int partition = start_partition; - partition < start_partition + num_partitions; - ++partition) - { - OsdDrawContext::PatchArrayVector const &patches = - mesh->GetPatchArrays(partition); - for (int i = 0; i < (int)patches.size(); ++i) { - OsdDrawContext::PatchArray const &patch = patches[i]; - OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor(); - OpenSubdiv::FarPatchTables::Type patchType = desc.GetType(); - if (patchType == OpenSubdiv::FarPatchTables::QUADS) { - if (start_element == -1) { - patch_index = patch.GetPatchIndex(); - start_element = patch.GetVertIndex(); - } + int traversed_patches = 0, num_remained_patches = num_patches; + const OpenSubdiv::Osd::PatchArrayVector& patches = + mesh->GetPatchTable()->GetPatchArrays(); + for (int i = 0; i < (int)patches.size(); ++i) { + const OpenSubdiv::Osd::PatchArray& patch = patches[i]; + OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor(); + OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType(); - assert(patch.GetVertIndex() == start_element + num_elements); - num_elements += patch.GetNumIndices(); + if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) { + const int num_block_patches = patch.GetNumPatches(); + if (start_patch >= traversed_patches && + start_patch < traversed_patches + num_block_patches) + { + const int num_control_verts = desc.GetNumControlVertices(); + const int start_draw_patch = start_patch - traversed_patches; + const int num_draw_patches = std::min(num_remained_patches, + num_block_patches - start_draw_patch); + perform_drawElements(program, + i, + num_draw_patches * num_control_verts, + patch.GetIndexBase() + start_draw_patch * num_control_verts); + num_remained_patches -= num_draw_patches; } - else { - assert(!"Discontinuitied are not supported yet."); + if (num_remained_patches == 0) { + break; } + traversed_patches += num_block_patches; } - } - - /* Perform actual draw. */ - perform_drawElements(program, - patch_index, - num_elements, - start_element); + } } -#endif -static void draw_all_patches(PartitionedGLMeshInterface *mesh, +static void draw_all_patches(GLMeshInterface *mesh, GLuint program) { const OpenSubdiv::Osd::PatchArrayVector& patches = @@ -620,30 +645,25 @@ static void draw_all_patches(PartitionedGLMeshInterface *mesh, void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, int fill_quads, - int start_partition, - int num_partitions) + int start_patch, + int num_patches) { - PartitionedGLMeshInterface *mesh = - (PartitionedGLMeshInterface *)(gl_mesh->descriptor); + GLMeshInterface *mesh = + (GLMeshInterface *)(gl_mesh->descriptor); /* Make sure all global invariants are initialized. */ - openSubdiv_osdGLDisplayInit(); + if (!openSubdiv_osdGLDisplayInit()) { + return; + } /* Setup GLSL/OpenGL to draw patches in current context. */ GLuint program = preapre_patchDraw(mesh, fill_quads != 0); - if (start_partition != -1) { -#if 0 + if (start_patch != -1) { draw_partition_patches_range(mesh, program, - start_partition, - num_partitions); -#else - (void)num_partitions; - if(start_partition == 0) { - draw_all_patches(mesh, program); - } -#endif + start_patch, + num_patches); } else { draw_all_patches(mesh, program); diff --git a/intern/opensubdiv/opensubdiv_intern.h b/intern/opensubdiv/opensubdiv_intern.h index 3e3925e74c4..ccb32f9d0ac 100644 --- a/intern/opensubdiv/opensubdiv_intern.h +++ b/intern/opensubdiv/opensubdiv_intern.h @@ -30,7 +30,10 @@ #ifdef NDEBUG # undef OPENSUBDIV_VALIDATE_TOPOLOGY #else -# define OPENSUBDIV_VALIDATE_TOPOLOGY +/* TODO(sergey): Always disabled for now, the check doesn't handle + * multiple non-manifolds from the OpenSubdiv side currently. + */ +# undef OPENSUBDIV_VALIDATE_TOPOLOGY #endif /* Currently OpenSubdiv expects topology to be oriented, diff --git a/intern/opensubdiv/opensubdiv_partitioned.h b/intern/opensubdiv/opensubdiv_partitioned.h deleted file mode 100644 index 7394a83cd0a..00000000000 --- a/intern/opensubdiv/opensubdiv_partitioned.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2013 Blender Foundation. - * All rights reserved. - * - * Contributor(s): Sergey Sharybin - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __OPENSUBDIV_PATITIONED_H__ -#define __OPENSUBDIV_PATITIONED_H__ - -#include <opensubdiv/osd/glMesh.h> -#include <opensubdiv/osd/cpuEvaluator.h> -#include <opensubdiv/osd/glVertexBuffer.h> - -namespace OpenSubdiv { -namespace OPENSUBDIV_VERSION { -namespace Osd { - -/* TODO(sergey): Re-implement partitioning. */ - -#if 0 -template <class PATCH_TABLE> -class PartitionedMeshInterface : public MeshInterface<PATCH_TABLE> { - typedef PATCH_TABLE PatchTable; - typedef typename PatchTable::VertexBufferBinding VertexBufferBinding; - -public: -}; - -typedef PartitionedMeshInterface<GLPatchTable> PartitionedGLMeshInterface; - -#endif - -#if 0 -template <typename VERTEX_BUFFER, - typename STENCIL_TABLE, - typename EVALUATOR, - typename PATCH_TABLE, - typename DEVICE_CONTEXT = void> -class PartitionedMesh : public Mesh<VERTEX_BUFFER, - STENCIL_TABLE, - EVALUATOR, - PATCH_TABLE, - DEVICE_CONTEXT> -{ -}; -#endif - -#define PartitionedGLMeshInterface GLMeshInterface -#define PartitionedMesh Mesh - -} /* namespace Osd */ -} /* namespace OPENSUBDIV_VERSION */ - -using namespace OPENSUBDIV_VERSION; - -} /* namespace OpenSubdiv */ - -#endif /* __OPENSUBDIV_PATITIONED_H__ */ diff --git a/intern/opensubdiv/opensubdiv_utils_capi.cc b/intern/opensubdiv/opensubdiv_utils_capi.cc index 5a2d017ed26..a945484ba61 100644 --- a/intern/opensubdiv/opensubdiv_utils_capi.cc +++ b/intern/opensubdiv/opensubdiv_utils_capi.cc @@ -26,6 +26,7 @@ #include "opensubdiv_capi.h" +#include <cstring> #include <GL/glew.h> #ifdef _MSC_VER @@ -71,12 +72,38 @@ int openSubdiv_getAvailableEvaluators(void) #endif /* OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK */ #ifdef OPENSUBDIV_HAS_GLSL_COMPUTE - flags |= OPENSUBDIV_EVALUATOR_GLSL_COMPUTE; + static bool vendor_checked = false; + static bool disable_glsl_compute = false; + /* Force disable GLSL Compute on AMD hardware because it has really + * hard time evaluating required shaders. + */ + if (!vendor_checked) { + vendor_checked = true; + const char *vendor = (const char *)glGetString(GL_VENDOR); + const char *renderer = (const char *)glGetString(GL_RENDERER); + if (vendor != NULL && renderer != NULL) { + if (strstr(vendor, "ATI") || + strstr(renderer, "Mesa DRI R") || + (strstr(renderer, "Gallium ") && strstr(renderer, " on ATI "))) + { + disable_glsl_compute = true; + } + } + } + if (!disable_glsl_compute) { + flags |= OPENSUBDIV_EVALUATOR_GLSL_COMPUTE; + } #endif /* OPENSUBDIV_HAS_GLSL_COMPUTE */ return flags; } +void openSubdiv_init(void) +{ + /* Ensure all OpenGL strings are cached. */ + (void)openSubdiv_getAvailableEvaluators(); +} + void openSubdiv_cleanup(void) { openSubdiv_osdGLDisplayDeinit(); diff --git a/intern/smoke/intern/MERSENNETWISTER.h b/intern/smoke/intern/MERSENNETWISTER.h index 5a9ccf88ae7..42b3fe19686 100644 --- a/intern/smoke/intern/MERSENNETWISTER.h +++ b/intern/smoke/intern/MERSENNETWISTER.h @@ -187,7 +187,7 @@ inline MTRand::uint32 MTRand::randInt() if( left == 0 ) reload(); --left; - register uint32 s1; + uint32 s1; s1 = *pNext++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680UL; @@ -232,9 +232,9 @@ inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) // in each element are discarded. // Just call seed() if you want to get array from /dev/urandom initialize(19650218UL); - register int i = 1; - register uint32 j = 0; - register int k = ( (uint32)N > seedLength ? (uint32)N : seedLength ); + int i = 1; + uint32 j = 0; + int k = ( (uint32)N > seedLength ? (uint32)N : seedLength ); for( ; k; --k ) { state[i] = @@ -273,9 +273,9 @@ inline void MTRand::seed() if( urandom ) { uint32 bigSeed[N]; - register uint32 *s = bigSeed; - register int i = N; - register bool success = true; + uint32 *s = bigSeed; + int i = N; + bool success = true; while( success && i-- ) success = fread( s++, sizeof(uint32), 1, urandom ); fclose(urandom); @@ -294,9 +294,9 @@ inline void MTRand::initialize( const uint32 seed ) // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. // In previous versions, most significant bits (MSBs) of the seed affect // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - register uint32 *s = state; - register uint32 *r = state; - register int i = 1; + uint32 *s = state; + uint32 *r = state; + int i = 1; *s++ = seed & 0xffffffffUL; for( ; i < N; ++i ) { @@ -310,8 +310,8 @@ inline void MTRand::reload() { // Generate N new values in state // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - register uint32 *p = state; - register int i; + uint32 *p = state; + int i; for( i = N - M; i--; ++p ) *p = twist( p[M], p[0], p[1] ); for( i = M; --i; ++p ) @@ -350,9 +350,9 @@ inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) inline void MTRand::save( uint32* saveArray ) const { - register uint32 *sa = saveArray; - register const uint32 *s = state; - register int i = N; + uint32 *sa = saveArray; + const uint32 *s = state; + int i = N; for( ; i--; *sa++ = *s++ ) {} *sa = left; } @@ -360,9 +360,9 @@ inline void MTRand::save( uint32* saveArray ) const inline void MTRand::load( uint32 *const loadArray ) { - register uint32 *s = state; - register uint32 *la = loadArray; - register int i = N; + uint32 *s = state; + uint32 *la = loadArray; + int i = N; for( ; i--; *s++ = *la++ ) {} left = *la; pNext = &state[N-left]; @@ -371,8 +371,8 @@ inline void MTRand::load( uint32 *const loadArray ) inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) { - register const MTRand::uint32 *s = mtrand.state; - register int i = mtrand.N; + const MTRand::uint32 *s = mtrand.state; + int i = mtrand.N; for( ; i--; os << *s++ << "\t" ) {} return os << mtrand.left; } @@ -380,8 +380,8 @@ inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) { - register MTRand::uint32 *s = mtrand.state; - register int i = mtrand.N; + MTRand::uint32 *s = mtrand.state; + int i = mtrand.N; for( ; i--; is >> *s++ ) {} is >> mtrand.left; mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; |