1
1

Compare commits

..

1 Commits

Author SHA1 Message Date
2038250c62 WIP changes to compiling interface directory as C++ code 2021-04-28 23:32:55 -05:00
730 changed files with 9392 additions and 26078 deletions

View File

@@ -255,7 +255,6 @@ ForEachMacros:
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN
- SEQ_ALL_BEGIN
- SEQ_ITERATOR_FOREACH
- SURFACE_QUAD_ITER_BEGIN
- foreach
- ED_screen_areas_iter

View File

@@ -29,7 +29,7 @@ set(BLOSC_EXTRA_ARGS
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
)
# Prevent blosc from including its own local copy of zlib in the object file
# Prevent blosc from including it's own local copy of zlib in the object file
# and cause linker errors with everybody else.
set(BLOSC_EXTRA_ARGS ${BLOSC_EXTRA_ARGS}
-DPREFER_EXTERNAL_ZLIB=ON

View File

@@ -43,7 +43,7 @@ set(JPEG_FILE libjpeg-turbo-${JPEG_VERSION}.tar.gz)
set(BOOST_VERSION 1.73.0)
set(BOOST_VERSION_NODOTS 1_73_0)
set(BOOST_VERSION_NODOTS_SHORT 1_73)
set(BOOST_URI https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_NODOTS}.tar.gz)
set(BOOST_URI https://dl.bintray.com/boostorg/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_NODOTS}.tar.gz)
set(BOOST_HASH 4036cd27ef7548b8d29c30ea10956196)
set(BOOST_HASH_TYPE MD5)
set(BOOST_FILE boost_${BOOST_VERSION_NODOTS}.tar.gz)
@@ -297,10 +297,10 @@ set(OPENJPEG_HASH 63f5a4713ecafc86de51bfad89cc07bb788e9bba24ebbf0c4ca637621aadb6
set(OPENJPEG_HASH_TYPE SHA256)
set(OPENJPEG_FILE openjpeg-v${OPENJPEG_VERSION}.tar.gz)
set(FFMPEG_VERSION 4.4)
set(FFMPEG_VERSION 4.2.3)
set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
set(FFMPEG_HASH 42093549751b582cf0f338a21a3664f52e0a9fbe0d238d3c992005e493607d0e)
set(FFMPEG_HASH_TYPE SHA256)
set(FFMPEG_HASH 695fad11f3baf27784e24cb0e977b65a)
set(FFMPEG_HASH_TYPE MD5)
set(FFMPEG_FILE ffmpeg-${FFMPEG_VERSION}.tar.bz2)
set(FFTW_VERSION 3.3.8)

View File

@@ -37,7 +37,7 @@ if [ $USE_DEBUG_TRAP -ne 0 ]; then
trap 'err_report $LINENO' ERR
fi
# Noisy, show every line that runs with its line number.
# Noisy, show every line that runs with it's line number.
if [ $USE_DEBUG_LOG -ne 0 ]; then
PS4='\e[0;33m$(printf %4d ${LINENO}):\e\033[0m '
set -x
@@ -563,9 +563,9 @@ OIDN_SKIP=false
ISPC_VERSION="1.14.1"
FFMPEG_VERSION="4.4"
FFMPEG_VERSION_SHORT="4.4"
FFMPEG_VERSION_MIN="4.4"
FFMPEG_VERSION="4.2.3"
FFMPEG_VERSION_SHORT="4.2"
FFMPEG_VERSION_MIN="3.0"
FFMPEG_VERSION_MAX="5.0"
FFMPEG_FORCE_BUILD=false
FFMPEG_FORCE_REBUILD=false

View File

@@ -20,7 +20,7 @@
# ILMBASE_LIBRARIES - list of libraries to link against when using IlmBase.
# ILMBASE_FOUND - True if IlmBase was found.
# Other standard issue macros
# Other standarnd issue macros
include(FindPackageHandleStandardArgs)
include(FindPackageMessage)
include(SelectLibraryConfigurations)

View File

@@ -22,7 +22,7 @@
# These are defined by the FindIlmBase module.
# OPENEXR_FOUND - True if OpenEXR was found.
# Other standard issue macros
# Other standarnd issue macros
include(SelectLibraryConfigurations)
include(FindPackageHandleStandardArgs)
include(FindPackageMessage)

View File

@@ -79,7 +79,7 @@ if(EXISTS ${SOURCE_DIR}/.git)
ERROR_QUIET)
if(NOT _git_below_check STREQUAL "")
# If there're commits between HEAD and upstream this means
# that we're reset-ed to older revision. Use its hash then.
# that we're reset-ed to older revision. Use it's hash then.
execute_process(COMMAND git rev-parse --short=12 HEAD
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE MY_WC_HASH

View File

@@ -20,6 +20,12 @@
# Libraries configuration for Apple.
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
set(MACOSX_DEPLOYMENT_TARGET 11.00)
else()
set(MACOSX_DEPLOYMENT_TARGET 10.13)
endif()
macro(find_package_wrapper)
# do nothing, just satisfy the macro
endmacro()

View File

@@ -168,15 +168,21 @@ endif()
unset(OSX_SDKROOT)
# 10.13 is our min. target, if you use higher sdk, weak linking happens
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
# M1 chips run Big Sur onwards.
set(OSX_MIN_DEPLOYMENT_TARGET 11.00)
else()
# 10.13 is our min. target, if you use higher sdk, weak linking happens
set(OSX_MIN_DEPLOYMENT_TARGET 10.13)
endif()
set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
if(CMAKE_OSX_DEPLOYMENT_TARGET)
if(${CMAKE_OSX_DEPLOYMENT_TARGET} VERSION_LESS ${OSX_MIN_DEPLOYMENT_TARGET})
message(STATUS "Setting deployment target to ${OSX_MIN_DEPLOYMENT_TARGET}, lower versions are not supported")
set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
endif()
else()
set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
endif()
if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
# Force CMAKE_OSX_DEPLOYMENT_TARGET for makefiles, will not work else (CMake bug?)

View File

@@ -4,9 +4,7 @@ Simple Render Engine
"""
import bpy
import array
import gpu
from gpu_extras.presets import draw_texture_2d
import bgl
class CustomRenderEngine(bpy.types.RenderEngine):
@@ -102,7 +100,8 @@ class CustomRenderEngine(bpy.types.RenderEngine):
dimensions = region.width, region.height
# Bind shader that converts from scene linear to display space,
gpu.state.blend_set('ALPHA_PREMULT')
bgl.glEnable(bgl.GL_BLEND)
bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ONE_MINUS_SRC_ALPHA)
self.bind_display_space_shader(scene)
if not self.draw_data or self.draw_data.dimensions != dimensions:
@@ -111,7 +110,7 @@ class CustomRenderEngine(bpy.types.RenderEngine):
self.draw_data.draw()
self.unbind_display_space_shader()
gpu.state.blend_set('NONE')
bgl.glDisable(bgl.GL_BLEND)
class CustomDrawData:
@@ -120,21 +119,68 @@ class CustomDrawData:
self.dimensions = dimensions
width, height = dimensions
pixels = width * height * array.array('f', [0.1, 0.2, 0.1, 1.0])
pixels = gpu.types.Buffer('FLOAT', width * height * 4, pixels)
pixels = [0.1, 0.2, 0.1, 1.0] * width * height
pixels = bgl.Buffer(bgl.GL_FLOAT, width * height * 4, pixels)
# Generate texture
self.texture = gpu.types.GPUTexture((width, height), format='RGBA16F', data=pixels)
self.texture = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGenTextures(1, self.texture)
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture[0])
bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA16F, width, height, 0, bgl.GL_RGBA, bgl.GL_FLOAT, pixels)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
# Note: This is just a didactic example.
# In this case it would be more convenient to fill the texture with:
# self.texture.clear('FLOAT', value=[0.1, 0.2, 0.1, 1.0])
# Bind shader that converts from scene linear to display space,
# use the scene's color management settings.
shader_program = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, shader_program)
# Generate vertex array
self.vertex_array = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGenVertexArrays(1, self.vertex_array)
bgl.glBindVertexArray(self.vertex_array[0])
texturecoord_location = bgl.glGetAttribLocation(shader_program[0], "texCoord")
position_location = bgl.glGetAttribLocation(shader_program[0], "pos")
bgl.glEnableVertexAttribArray(texturecoord_location)
bgl.glEnableVertexAttribArray(position_location)
# Generate geometry buffers for drawing textured quad
position = [0.0, 0.0, width, 0.0, width, height, 0.0, height]
position = bgl.Buffer(bgl.GL_FLOAT, len(position), position)
texcoord = [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0]
texcoord = bgl.Buffer(bgl.GL_FLOAT, len(texcoord), texcoord)
self.vertex_buffer = bgl.Buffer(bgl.GL_INT, 2)
bgl.glGenBuffers(2, self.vertex_buffer)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[0])
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, position, bgl.GL_STATIC_DRAW)
bgl.glVertexAttribPointer(position_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[1])
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, texcoord, bgl.GL_STATIC_DRAW)
bgl.glVertexAttribPointer(texturecoord_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0)
bgl.glBindVertexArray(0)
def __del__(self):
del self.texture
bgl.glDeleteBuffers(2, self.vertex_buffer)
bgl.glDeleteVertexArrays(1, self.vertex_array)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
bgl.glDeleteTextures(1, self.texture)
def draw(self):
draw_texture_2d(self.texture, (0, 0), self.texture.width, self.texture.height)
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture[0])
bgl.glBindVertexArray(self.vertex_array[0])
bgl.glDrawArrays(bgl.GL_TRIANGLE_FAN, 0, 4)
bgl.glBindVertexArray(0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
# RenderEngines also need to tell UI Panels that they are compatible with.

View File

@@ -4,6 +4,7 @@ Mesh with Random Vertex Colors
"""
import bpy
import gpu
import bgl
import numpy as np
from random import random
from gpu_extras.batch import batch_for_shader
@@ -30,10 +31,9 @@ batch = batch_for_shader(
def draw():
gpu.state.depth_test_set('LESS_EQUAL')
gpu.state.depth_mask_set(True)
bgl.glEnable(bgl.GL_DEPTH_TEST)
batch.draw(shader)
gpu.state.depth_mask_set(False)
bgl.glDisable(bgl.GL_DEPTH_TEST)
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')

View File

@@ -6,11 +6,11 @@ To use this example you have to provide an image that should be displayed.
"""
import bpy
import gpu
import bgl
from gpu_extras.batch import batch_for_shader
IMAGE_NAME = "Untitled"
image = bpy.data.images[IMAGE_NAME]
texture = gpu.texture.from_image(image)
shader = gpu.shader.from_builtin('2D_IMAGE')
batch = batch_for_shader(
@@ -21,9 +21,16 @@ batch = batch_for_shader(
},
)
if image.gl_load():
raise Exception()
def draw():
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)
shader.bind()
shader.uniform_sampler("image", texture)
shader.uniform_int("image", 0)
batch.draw(shader)

View File

@@ -9,6 +9,7 @@ Generate a texture using Offscreen Rendering
"""
import bpy
import gpu
import bgl
from mathutils import Matrix
from gpu_extras.batch import batch_for_shader
from gpu_extras.presets import draw_circle_2d
@@ -19,8 +20,8 @@ from gpu_extras.presets import draw_circle_2d
offscreen = gpu.types.GPUOffScreen(512, 512)
with offscreen.bind():
fb = gpu.state.active_framebuffer_get()
fb.clear(color=(0.0, 0.0, 0.0, 0.0))
bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
with gpu.matrix.push_pop():
# reset matrices -> use normalized device coordinates [-1, 1]
gpu.matrix.load_matrix(Matrix.Identity(4))
@@ -74,10 +75,13 @@ batch = batch_for_shader(
def draw():
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture)
shader.bind()
shader.uniform_float("modelMatrix", Matrix.Translation((1, 2, 3)) @ Matrix.Scale(3, 4))
shader.uniform_float("viewProjectionMatrix", bpy.context.region_data.perspective_matrix)
shader.uniform_sampler("image", offscreen.texture_color)
shader.uniform_float("image", 0)
batch.draw(shader)

View File

@@ -7,10 +7,11 @@ If it already exists, it will override the existing one.
Currently almost all of the execution time is spent in the last line.
In the future this will hopefully be solved by implementing the Python buffer protocol
for :class:`gpu.types.Buffer` and :class:`bpy.types.Image.pixels` (aka ``bpy_prop_array``).
for :class:`bgl.Buffer` and :class:`bpy.types.Image.pixels` (aka ``bpy_prop_array``).
"""
import bpy
import gpu
import bgl
import random
from mathutils import Matrix
from gpu_extras.presets import draw_circle_2d
@@ -24,8 +25,8 @@ RING_AMOUNT = 10
offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)
with offscreen.bind():
fb = gpu.state.active_framebuffer_get()
fb.clear(color=(0.0, 0.0, 0.0, 0.0))
bgl.glClearColor(0.0, 0.0, 0.0, 0.0)
bgl.glClear(bgl.GL_COLOR_BUFFER_BIT)
with gpu.matrix.push_pop():
# reset matrices -> use normalized device coordinates [-1, 1]
gpu.matrix.load_matrix(Matrix.Identity(4))
@@ -36,7 +37,9 @@ with offscreen.bind():
(random.uniform(-1, 1), random.uniform(-1, 1)),
(1, 1, 1, 1), random.uniform(0.1, 1), 20)
buffer = fb.read_color(0, 0, WIDTH, HEIGHT, 4, 0, 'UBYTE')
buffer = bgl.Buffer(bgl.GL_BYTE, WIDTH * HEIGHT * 4)
bgl.glReadBuffer(bgl.GL_BACK)
bgl.glReadPixels(0, 0, WIDTH, HEIGHT, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
offscreen.free()
@@ -45,6 +48,4 @@ if not IMAGE_NAME in bpy.data.images:
bpy.data.images.new(IMAGE_NAME, WIDTH, HEIGHT)
image = bpy.data.images[IMAGE_NAME]
image.scale(WIDTH, HEIGHT)
buffer.dimensions = WIDTH * HEIGHT * 4
image.pixels = [v / 255 for v in buffer]

View File

@@ -7,6 +7,7 @@ You could also make this independent of a specific camera,
but Blender does not expose good functions to create view and projection matrices yet.
"""
import bpy
import bgl
import gpu
from gpu_extras.presets import draw_texture_2d
@@ -33,8 +34,8 @@ def draw():
view_matrix,
projection_matrix)
gpu.state.depth_mask_set(False)
draw_texture_2d(offscreen.texture_color, (10, 10), WIDTH, HEIGHT)
bgl.glDisable(bgl.GL_DEPTH_TEST)
draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT)
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')

View File

@@ -1,5 +0,0 @@
# Compute local object transformation matrix:
if obj.rotation_mode == 'QUATERNION':
matrix = mathutils.Matrix.LocRotScale(obj.location, obj.rotation_quaternion, obj.scale)
else:
matrix = mathutils.Matrix.LocRotScale(obj.location, obj.rotation_euler, obj.scale)

View File

@@ -14,14 +14,10 @@ mat_rot = mathutils.Matrix.Rotation(math.radians(45.0), 4, 'X')
mat_out = mat_loc @ mat_rot @ mat_sca
print(mat_out)
# extract components back out of the matrix as two vectors and a quaternion
# extract components back out of the matrix
loc, rot, sca = mat_out.decompose()
print(loc, rot, sca)
# recombine extracted components
mat_out2 = mathutils.Matrix.LocRotScale(loc, rot, sca)
print(mat_out2)
# it can also be useful to access components of a matrix directly
mat = mathutils.Matrix()
mat[0][0], mat[1][0], mat[2][0] = 0.0, 1.0, 2.0

View File

@@ -545,13 +545,6 @@ def range_str(val):
def example_extract_docstring(filepath):
'''
Return (text, line_no, line_no_has_content) where:
- ``text`` is the doc-string text.
- ``line_no`` is the line the doc-string text ends.
- ``line_no_has_content`` when False, this file only contains a doc-string.
There is no need to include the remainder.
'''
file = open(filepath, "r", encoding="utf-8")
line = file.readline()
line_no = 0
@@ -560,7 +553,7 @@ def example_extract_docstring(filepath):
line_no += 1
else:
file.close()
return "", 0, True
return "", 0, False
for line in file:
line_no += 1
@@ -1036,6 +1029,7 @@ def pymodule2sphinx(basepath, module_name, module, title, module_all_extra):
context_type_map = {
# context_member: (RNA type, is_collection)
"active_annotation_layer": ("GPencilLayer", False),
"active_base": ("ObjectBase", False),
"active_bone": ("EditBone", False),
"active_gpencil_frame": ("GreasePencilLayer", True),
"active_gpencil_layer": ("GPencilLayer", True),
@@ -1555,8 +1549,8 @@ def pyrna2sphinx(basepath):
fw(".. hlist::\n")
fw(" :columns: 2\n\n")
# Context does its own thing.
# "active_object": ("Object", False),
# context does its own thing
# "active_base": ("ObjectBase", False),
for ref_attr, (ref_type, ref_is_seq) in sorted(context_type_map.items()):
if ref_type == struct_id:
fw(" * :mod:`bpy.context.%s`\n" % ref_attr)

View File

@@ -1,8 +1,7 @@
/* T76453: Prevent Long enum lists */
.field-list > dd p {
.field-list li {
max-height: 245px;
overflow-y: auto !important;
word-break: break-word;
}
/* Hide home icon in search area */
@@ -12,15 +11,3 @@
.wy-nav-content {
max-width: 1000px !important;
}
/* Fix long titles on mobile */
h1, h2, h3, h4, h5, h6 {word-break: break-all}
/* Temp fix for https://github.com/readthedocs/sphinx_rtd_theme/pull/1109 */
.hlist tr {
display: -ms-flexbox;
display: flex;
flex-flow: row wrap;
}
.hlist td {margin-right: auto}

View File

@@ -29,10 +29,10 @@
#if OPENVDB == 1
# include "openvdb/openvdb.h"
# include "openvdb/points/PointConversion.h"
# include "openvdb/points/PointCount.h"
# include "openvdb/tools/Clip.h"
# include "openvdb/tools/Dense.h"
# include <openvdb/points/PointConversion.h>
# include <openvdb/points/PointCount.h>
# include <openvdb/tools/Clip.h>
# include <openvdb/tools/Dense.h>
#endif
#define POSITION_NAME "P"
@@ -519,7 +519,7 @@ int writeObjectsVDB(const string &filename,
}
}
// Write only if there is at least one grid, optionally write with compression.
// Write only if the is at least one grid, optionally write with compression.
if (gridsVDB.size()) {
int vdb_flags = openvdb::io::COMPRESS_ACTIVE_MASK;
switch (compression) {
@@ -534,8 +534,7 @@ int writeObjectsVDB(const string &filename,
}
case COMPRESSION_BLOSC: {
# if OPENVDB_BLOSC == 1
// Cannot use |= here, causes segfault with blosc 1.5.0 (== recommended version)
vdb_flags = openvdb::io::COMPRESS_BLOSC;
vdb_flags |= openvdb::io::COMPRESS_BLOSC;
# else
debMsg("OpenVDB was built without Blosc support, using Zip compression instead", 1);
vdb_flags |= openvdb::io::COMPRESS_ZIP;

View File

@@ -384,7 +384,6 @@ class FluidSolver : public PbClass {
GridStorage<Real> mGrids4dReal;
GridStorage<Vec3> mGrids4dVec;
GridStorage<Vec4> mGrids4dVec4;
public:
PbArgs _args;
}

View File

@@ -42,7 +42,7 @@ inline void updateQtGui(bool full, int frame, float time, const std::string &cur
# ifdef _DEBUG
# define DEBUG 1
# endif // _DEBUG
#endif // DEBUG
#endif // DEBUG
// Standard exception
class Error : public std::exception {

View File

@@ -1,3 +1,3 @@
#define MANTA_GIT_VERSION "commit 9c505cd22e289b98c9aa717efba8ef3201c7e458"
#define MANTA_GIT_VERSION "commit 39b7a415721ecbf6643612a24e8eadd221aeb934"

View File

@@ -389,7 +389,6 @@ class GridBase : public PbClass {
Real mDx;
bool m3D; // precomputed Z shift: to ensure 2D compatibility, always use this instead of sx*sy !
IndexInt mStrideZ;
public:
PbArgs _args;
}

View File

@@ -326,7 +326,6 @@ class Grid4dBase : public PbClass {
// precomputed Z,T shift: to ensure 2D compatibility, always use this instead of sx*sy !
IndexInt mStrideZ;
IndexInt mStrideT;
public:
PbArgs _args;
}
@@ -951,7 +950,6 @@ template<class T> class Grid4d : public Grid4dBase {
protected:
T *mData;
public:
PbArgs _args;
}

View File

@@ -266,7 +266,6 @@ class LevelsetGrid : public Grid<Real> {
}
static Real invalidTimeValue();
public:
PbArgs _args;
}

View File

@@ -796,7 +796,6 @@ class Mesh : public PbClass {
std::vector<MeshDataImpl<int> *>
mMdataInt; //! indicate that mdata of this mesh is copied, and needs to be freed
bool mFreeMdata;
public:
PbArgs _args;
}
@@ -882,7 +881,6 @@ class MeshDataBase : public PbClass {
protected:
Mesh *mMesh;
public:
PbArgs _args;
}
@@ -1647,7 +1645,6 @@ template<class T> class MeshDataImpl : public MeshDataBase {
//! optionally , we might have an associated grid from which to grab new data
Grid<T> *mpGridSource; //! unfortunately , we need to distinguish mac vs regular vec3
bool mGridSourceMAC;
public:
PbArgs _args;
}

View File

@@ -154,7 +154,6 @@ class MovingObstacle : public PbClass {
int mEmptyType;
int mID;
static int sIDcnt;
public:
PbArgs _args;
}

View File

@@ -236,7 +236,6 @@ class WaveletNoiseField : public PbClass {
static int randomSeed;
// global reference count for noise tile
static std::atomic<int> mNoiseReferenceCount;
public:
PbArgs _args;
}

View File

@@ -205,7 +205,6 @@ class ParticleBase : public PbClass {
//! custom seed for particle systems, used by plugins
int mSeed; //! fix global random seed storage, used mainly by functions in this class
static int globalSeed;
public:
PbArgs _args;
}
@@ -629,7 +628,6 @@ template<class S> class ParticleSystem : public ParticleBase {
std::vector<S> mData;
//! reduce storage , called by doCompress
virtual void compress();
public:
PbArgs _args;
}
@@ -920,7 +918,6 @@ class ParticleIndexSystem : public ParticleSystem<ParticleIndexData> {
return -1;
}
};
public:
PbArgs _args;
}
@@ -985,7 +982,6 @@ template<class DATA, class CON> class ConnectedParticleSystem : public ParticleS
protected:
std::vector<CON> mSegments;
virtual void compress();
public:
PbArgs _args;
}
@@ -1075,7 +1071,6 @@ class ParticleDataBase : public PbClass {
protected:
ParticleBase *mpParticleSys;
public:
PbArgs _args;
}
@@ -1848,7 +1843,6 @@ template<class T> class ParticleDataImpl : public ParticleDataBase {
//! optionally , we might have an associated grid from which to grab new data
Grid<T> *mpGridSource; //! unfortunately , we need to distinguish mac vs regular vec3
bool mGridSourceMAC;
public:
PbArgs _args;
}

View File

@@ -234,10 +234,10 @@ void subdivideMesh(
normalize(ne2);
// Real thisArea = sqrMag(cross(-e2,e0));
// small angle approximation says sin(x) = arcsin(x) = x,
// arccos(x) = pi/2 - arcsin(x),
// cos(x) = dot(A,B),
// so angle is approximately 1 - dot(A,B).
// small angle approximation says sin(x) = arcsin(x) = x,
// arccos(x) = pi/2 - arcsin(x),
// cos(x) = dot(A,B),
// so angle is approximately 1 - dot(A,B).
Real angle[3];
angle[0] = 1.0 - dot(ne0, -ne2);
angle[1] = 1.0 - dot(ne1, -ne0);

View File

@@ -2287,10 +2287,9 @@ struct knFlipComputePotentialTrappedAir : public KernelBase {
const Vec3 &vj = scaleFromManta * v.getCentered(x, y, z);
const Vec3 xij = xi - xj;
const Vec3 vij = vi - vj;
Real h = !pot.is3D() ?
1.414 * radius :
1.732 * radius; // estimate sqrt(2)*radius resp. sqrt(3)*radius for h, due
// to squared resp. cubic neighbor area
Real h = !pot.is3D() ? 1.414 * radius :
1.732 * radius; // estimate sqrt(2)*radius resp. sqrt(3)*radius
// for h, due to squared resp. cubic neighbor area
vdiff += norm(vij) * (1 - dot(getNormalized(vij), getNormalized(xij))) *
(1 - norm(xij) / h);
}

View File

@@ -269,7 +269,6 @@ class Shape : public PbClass {
protected:
GridType mType;
public:
PbArgs _args;
}
@@ -320,7 +319,6 @@ class NullShape : public Shape {
{
gridSetConst<Real>(phi, 1000.0f);
}
public:
PbArgs _args;
}
@@ -396,7 +394,6 @@ class Box : public Shape {
protected:
Vec3 mP0, mP1;
public:
PbArgs _args;
}
@@ -458,7 +455,6 @@ class Sphere : public Shape {
protected:
Vec3 mCenter, mScale;
Real mRadius;
public:
PbArgs _args;
}
@@ -583,7 +579,6 @@ class Cylinder : public Shape {
protected:
Vec3 mCenter, mZDir;
Real mRadius, mZ;
public:
PbArgs _args;
}
@@ -660,7 +655,6 @@ class Slope : public Shape {
Real mAnglexy, mAngleyz;
Real mOrigin;
Vec3 mGs;
public:
PbArgs _args;
}

View File

@@ -199,7 +199,6 @@ class TurbulenceParticleSystem : public ParticleSystem<TurbulenceParticleData> {
private:
WaveletNoiseField &noise;
public:
PbArgs _args;
}

View File

@@ -127,7 +127,6 @@ class VortexParticleSystem : public ParticleSystem<VortexParticleData> {
}
virtual ParticleBase *clone();
public:
PbArgs _args;
}

View File

@@ -240,7 +240,6 @@ class VortexSheetMesh : public Mesh {
VorticityChannel mVorticity;
TexCoord3Channel mTex1, mTex2;
TurbulenceChannel mTurb;
public:
PbArgs _args;
}

View File

@@ -118,7 +118,6 @@ typedef struct CLG_LogType {
typedef struct CLG_LogRef {
const char *identifier;
CLG_LogType *type;
struct CLG_LogRef *next;
} CLG_LogRef;
void CLG_log_str(CLG_LogType *lg,

View File

@@ -81,8 +81,6 @@ typedef struct CLG_IDFilter {
typedef struct CLogContext {
/** Single linked list of types. */
CLG_LogType *types;
/** Single linked list of references. */
CLG_LogRef *refs;
#ifdef WITH_CLOG_PTHREADS
pthread_mutex_t types_lock;
#endif
@@ -322,9 +320,7 @@ static bool clg_ctx_filter_check(CLogContext *ctx, const char *identifier)
if (flt->match[0] == '*' && flt->match[len - 1] == '*') {
char *match = MEM_callocN(sizeof(char) * len - 1, __func__);
memcpy(match, flt->match + 1, len - 2);
const bool success = (strstr(identifier, match) != NULL);
MEM_freeN(match);
if (success) {
if (strstr(identifier, match) != NULL) {
return (bool)i;
}
}
@@ -677,12 +673,6 @@ static void CLG_ctx_free(CLogContext *ctx)
MEM_freeN(item);
}
while (ctx->refs != NULL) {
CLG_LogRef *item = ctx->refs;
ctx->refs = item->next;
item->type = NULL;
}
for (uint i = 0; i < 2; i++) {
while (ctx->filters[i] != NULL) {
CLG_IDFilter *item = ctx->filters[i];
@@ -779,10 +769,6 @@ void CLG_logref_init(CLG_LogRef *clg_ref)
pthread_mutex_lock(&g_ctx->types_lock);
#endif
if (clg_ref->type == NULL) {
/* Add to the refs list so we can NULL the pointers to 'type' when CLG_exit() is called. */
clg_ref->next = g_ctx->refs;
g_ctx->refs = clg_ref;
CLG_LogType *clg_ty = clg_ctx_type_find_by_name(g_ctx, clg_ref->identifier);
if (clg_ty == NULL) {
clg_ty = clg_ctx_type_register(g_ctx, clg_ref->identifier);

View File

@@ -71,16 +71,6 @@ if(WITH_CYCLES_STANDALONE)
target_link_libraries(cycles ${LIBRARIES})
cycles_target_link_libraries(cycles)
if(APPLE)
if(WITH_OPENCOLORIO)
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework IOKit")
endif()
if(WITH_OPENIMAGEDENOISE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
# OpenImageDenoise uses BNNS from the Accelerate framework.
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework Accelerate")
endif()
endif()
if(UNIX AND NOT APPLE)
set_target_properties(cycles PROPERTIES INSTALL_RPATH $ORIGIN/lib)
endif()

View File

@@ -19,16 +19,16 @@ from __future__ import annotations
def _is_using_buggy_driver():
import gpu
import bgl
# We need to be conservative here because in multi-GPU systems display card
# might be quite old, but others one might be just good.
#
# So We shouldn't disable possible good dedicated cards just because display
# card seems weak. And instead we only blacklist configurations which are
# proven to cause problems.
if gpu.platform.vendor_get() == "ATI Technologies Inc.":
if bgl.glGetString(bgl.GL_VENDOR) == "ATI Technologies Inc.":
import re
version = gpu.platform.version_get()
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 those cards do not quite work and

View File

@@ -552,9 +552,7 @@ class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
if world:
light = world.light_settings
col = layout.column(align=True)
col.prop(light, "ao_factor", text="AO Factor")
col.prop(light, "distance", text="AO Distance")
layout.prop(light, "distance", text="AO Distance")
class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
@@ -725,7 +723,7 @@ class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
col.prop(cscene, "tile_order", text="Order")
sub = col.column()
sub.active = not rd.use_save_buffers and not cscene.use_adaptive_sampling
sub.active = not rd.use_save_buffers
sub.prop(cscene, "use_progressive_refine")

View File

@@ -96,49 +96,7 @@ bool BlenderSync::object_is_light(BL::Object &b_ob)
return (b_ob_data && b_ob_data.is_a(&RNA_Light));
}
void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object)
{
/* Initialize motion blur for object, detecting if it's enabled and creating motion
* steps array if so. */
array<Transform> motion;
object->set_motion(motion);
Scene::MotionType need_motion = scene->need_motion();
if (need_motion == Scene::MOTION_NONE || !object->get_geometry()) {
return;
}
Geometry *geom = object->get_geometry();
geom->set_use_motion_blur(false);
geom->set_motion_steps(0);
uint motion_steps;
if (need_motion == Scene::MOTION_BLUR) {
motion_steps = object_motion_steps(b_parent, b_ob, Object::MAX_MOTION_STEPS);
geom->set_motion_steps(motion_steps);
if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
geom->set_use_motion_blur(true);
}
}
else {
motion_steps = 3;
geom->set_motion_steps(motion_steps);
}
motion.resize(motion_steps, transform_empty());
if (motion_steps) {
motion[motion_steps / 2] = object->get_tfm();
/* update motion socket before trying to access object->motion_time */
object->set_motion(motion);
for (size_t step = 0; step < motion_steps; step++) {
motion_times.insert(object->motion_time(step));
}
}
}
/* Object */
Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
BL::ViewLayer &b_view_layer,
@@ -261,8 +219,10 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
}
/* test if we need to sync */
bool object_updated = object_map.add_or_update(&object, b_ob, b_parent, key) ||
(tfm != object->get_tfm());
bool object_updated = false;
if (object_map.add_or_update(&object, b_ob, b_parent, key))
object_updated = true;
/* mesh sync */
/* b_ob is owned by the iterator and will go out of scope at the end of the block.
@@ -311,11 +271,49 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
* transform comparison should not be needed, but duplis don't work perfect
* in the depsgraph and may not signal changes, so this is a workaround */
if (object->is_modified() || object_updated ||
(object->get_geometry() && object->get_geometry()->is_modified())) {
(object->get_geometry() && object->get_geometry()->is_modified()) ||
tfm != object->get_tfm()) {
object->name = b_ob.name().c_str();
object->set_pass_id(b_ob.pass_index());
object->set_color(get_float3(b_ob.color()));
object->set_tfm(tfm);
array<Transform> motion;
object->set_motion(motion);
/* motion blur */
Scene::MotionType need_motion = scene->need_motion();
if (need_motion != Scene::MOTION_NONE && object->get_geometry()) {
Geometry *geom = object->get_geometry();
geom->set_use_motion_blur(false);
geom->set_motion_steps(0);
uint motion_steps;
if (need_motion == Scene::MOTION_BLUR) {
motion_steps = object_motion_steps(b_parent, b_ob, Object::MAX_MOTION_STEPS);
geom->set_motion_steps(motion_steps);
if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
geom->set_use_motion_blur(true);
}
}
else {
motion_steps = 3;
geom->set_motion_steps(motion_steps);
}
motion.resize(motion_steps, transform_empty());
if (motion_steps) {
motion[motion_steps / 2] = tfm;
/* update motion socket before trying to access object->motion_time */
object->set_motion(motion);
for (size_t step = 0; step < motion_steps; step++) {
motion_times.insert(object->motion_time(step));
}
}
}
/* dupli texture coordinates and random_id */
if (is_instance) {
@@ -333,8 +331,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
object->tag_update(scene);
}
sync_object_motion_init(b_parent, b_ob, object);
if (is_instance) {
/* Sync possible particle data. */
sync_dupli_particle(b_parent, b_instance, object);
@@ -564,12 +560,10 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
if (!cancel && !motion) {
sync_background_light(b_v3d, use_portal);
/* Handle removed data and modified pointers, as this may free memory, delete Nodes in the
* right order to ensure that dependent data is freed after their users. Objects should be
* freed before particle systems and geometries. */
/* handle removed data and modified pointers */
light_map.post_sync();
object_map.post_sync();
geometry_map.post_sync();
object_map.post_sync();
particle_system_map.post_sync();
}
@@ -617,7 +611,7 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
if (b_cam) {
sync_camera_motion(b_render, b_cam, width, height, 0.0f);
}
sync_objects(b_depsgraph, b_v3d);
sync_objects(b_depsgraph, b_v3d, 0.0f);
}
/* Insert motion times from camera. Motion times from other objects

View File

@@ -35,7 +35,6 @@
#include "util/util_path.h"
#include "util/util_string.h"
#include "util/util_task.h"
#include "util/util_tbb.h"
#include "util/util_types.h"
#ifdef WITH_OSL
@@ -289,11 +288,9 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *args)
RNA_pointer_create(NULL, &RNA_Depsgraph, (ID *)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
BL::Depsgraph b_depsgraph(depsgraphptr);
/* Allow Blender to execute other Python scripts, and isolate TBB tasks so we
* don't get deadlocks with Blender threads accessing shared data like images. */
python_thread_state_save(&session->python_thread_state);
tbb::this_task_arena::isolate([&] { session->render(b_depsgraph); });
session->render(b_depsgraph);
python_thread_state_restore(&session->python_thread_state);
@@ -330,8 +327,7 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
python_thread_state_save(&session->python_thread_state);
tbb::this_task_arena::isolate(
[&] { session->bake(b_depsgraph, b_object, pass_type, pass_filter, width, height); });
session->bake(b_depsgraph, b_object, pass_type, pass_filter, width, height);
python_thread_state_restore(&session->python_thread_state);
@@ -377,7 +373,7 @@ static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
python_thread_state_save(&session->python_thread_state);
tbb::this_task_arena::isolate([&] { session->reset_session(b_data, b_depsgraph); });
session->reset_session(b_data, b_depsgraph);
python_thread_state_restore(&session->python_thread_state);
@@ -399,7 +395,7 @@ static PyObject *sync_func(PyObject * /*self*/, PyObject *args)
python_thread_state_save(&session->python_thread_state);
tbb::this_task_arena::isolate([&] { session->synchronize(b_depsgraph); });
session->synchronize(b_depsgraph);
python_thread_state_restore(&session->python_thread_state);

View File

@@ -237,9 +237,6 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
sync->sync_recalc(b_depsgraph, b_v3d);
}
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, "");
BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render,

View File

@@ -1553,9 +1553,13 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
void BlenderSync::sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d)
{
/* for auto refresh images */
ImageManager *image_manager = scene->image_manager;
const int frame = b_scene.frame_current();
const bool auto_refresh_update = image_manager->set_animation_frame_update(frame);
bool auto_refresh_update = false;
if (preview) {
ImageManager *image_manager = scene->image_manager;
int frame = b_scene.frame_current();
auto_refresh_update = image_manager->set_animation_frame_update(frame);
}
shader_map.pre_sync();

View File

@@ -69,8 +69,7 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
experimental(false),
dicing_rate(1.0f),
max_subdivisions(12),
progress(progress),
has_updates_(true)
progress(progress)
{
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") :
@@ -85,9 +84,7 @@ BlenderSync::~BlenderSync()
void BlenderSync::reset(BL::BlendData &b_data, BL::Scene &b_scene)
{
/* Update data and scene pointers in case they change in session reset,
* for example after undo.
* Note that we do not modify the `has_updates_` flag here because the sync
* reset is also used during viewport navigation. */
* for example after undo. */
this->b_data = b_data;
this->b_scene = b_scene;
}
@@ -120,8 +117,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
if (dicing_prop_changed) {
has_updates_ = true;
for (const pair<const GeometryKey, Geometry *> &iter : geometry_map.key_to_scene_data()) {
Geometry *geom = iter.second;
if (geom->is_mesh()) {
@@ -138,12 +133,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
/* Iterate over all IDs in this depsgraph. */
for (BL::DepsgraphUpdate &b_update : b_depsgraph.updates) {
/* TODO(sergey): Can do more selective filter here. For example, ignore changes made to
* screen datablock. Note that sync_data() needs to be called after object deletion, and
* currently this is ensured by the scene ID tagged for update, which sets the `has_updates_`
* flag. */
has_updates_ = true;
BL::ID b_id(b_update.id());
/* Material */
@@ -224,18 +213,8 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
if (b_v3d) {
BlenderViewportParameters new_viewport_parameters(b_v3d);
if (viewport_parameters.modified(new_viewport_parameters)) {
world_recalc = true;
has_updates_ = true;
}
if (!has_updates_) {
Film *film = scene->film;
const PassType new_display_pass = new_viewport_parameters.get_viewport_display_render_pass(
b_v3d);
has_updates_ |= film->get_display_pass() != new_display_pass;
}
}
}
@@ -248,15 +227,11 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
int height,
void **python_thread_state)
{
if (!has_updates_) {
return;
}
scoped_timer timer;
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
sync_view_layer(b_view_layer);
sync_view_layer(b_v3d, b_view_layer);
sync_integrator();
sync_film(b_v3d);
sync_shaders(b_depsgraph, b_v3d);
@@ -279,8 +254,6 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
free_data_after_sync(b_depsgraph);
VLOG(1) << "Total time spent synchronizing data: " << timer.get_time();
has_updates_ = false;
}
/* Integrator */
@@ -451,7 +424,7 @@ void BlenderSync::sync_film(BL::SpaceView3D &b_v3d)
/* Render Layer */
void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer)
void BlenderSync::sync_view_layer(BL::SpaceView3D & /*b_v3d*/, BL::ViewLayer &b_view_layer)
{
view_layer.name = b_view_layer.name();
@@ -766,18 +739,12 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
* caches to be releases from blender side in order to reduce peak memory
* footprint during synchronization process.
*/
const bool is_interface_locked = b_engine.render() && b_engine.render().use_lock_interface();
const bool is_persistent_data = b_engine.render() && b_engine.render().use_persistent_data();
const bool can_free_caches =
(BlenderSession::headless || is_interface_locked) &&
/* Baking re-uses the depsgraph multiple times, clearing crashes
* reading un-evaluated mesh data which isn't aligned with the
* geometry we're baking, see T71012. */
!scene->bake_manager->get_baking() &&
/* Persistent data must main caches for performance and correctness. */
!is_persistent_data;
const bool can_free_caches = (BlenderSession::headless || is_interface_locked) &&
/* Baking re-uses the depsgraph multiple times, clearing crashes
* reading un-evaluated mesh data which isn't aligned with the
* geometry we're baking, see T71012. */
!scene->bake_manager->get_baking();
if (!can_free_caches) {
return;
}
@@ -902,9 +869,6 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
/* Clamp samples. */
params.samples = min(params.samples, Integrator::MAX_SAMPLES);
/* Adaptive sampling. */
params.adaptive_sampling = RNA_boolean_get(&cscene, "use_adaptive_sampling");
/* tiles */
const bool is_cpu = (params.device.type == DEVICE_CPU);
if (!is_cpu && !background) {
@@ -957,7 +921,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
BL::RenderSettings b_r = b_scene.render();
params.progressive_refine = b_engine.is_preview() ||
get_boolean(cscene, "use_progressive_refine");
if (b_r.use_save_buffers() || params.adaptive_sampling)
if (b_r.use_save_buffers())
params.progressive_refine = false;
if (background) {
@@ -993,6 +957,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
params.use_profiling = params.device.has_profiling && !b_engine.is_preview() && background &&
BlenderSession::print_render_stats;
params.adaptive_sampling = RNA_boolean_get(&cscene, "use_adaptive_sampling");
return params;
}

View File

@@ -73,7 +73,7 @@ class BlenderSync {
int width,
int height,
void **python_thread_state);
void sync_view_layer(BL::ViewLayer &b_view_layer);
void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer);
vector<Pass> sync_render_passes(BL::Scene &b_scene,
BL::RenderLayer &b_render_layer,
BL::ViewLayer &b_view_layer,
@@ -150,7 +150,6 @@ class BlenderSync {
BlenderObjectCulling &culling,
bool *use_portal,
TaskPool *geom_task_pool);
void sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object);
bool sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object);
@@ -264,12 +263,6 @@ class BlenderSync {
} view_layer;
Progress &progress;
protected:
/* Indicates that `sync_recalc()` detected changes in the scene.
* If this flag is false then the data is considered to be up-to-date and will not be
* synchronized at all. */
bool has_updates_ = true;
};
CCL_NAMESPACE_END

View File

@@ -32,26 +32,17 @@ BlenderViewportParameters::BlenderViewportParameters()
BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d)
: BlenderViewportParameters()
{
if (!b_v3d) {
return;
}
BL::View3DShading shading = b_v3d.shading();
/* We only copy the parameters if we are in look dev mode. otherwise
* defaults are being used. These defaults mimic normal render settings */
if (shading.type() != BL::View3DShading::type_RENDERED) {
return;
}
use_scene_world = shading.use_scene_world_render();
use_scene_lights = shading.use_scene_lights_render();
if (!use_scene_world) {
studiolight_rotate_z = shading.studiolight_rotate_z();
studiolight_intensity = shading.studiolight_intensity();
studiolight_background_alpha = shading.studiolight_background_alpha();
studiolight_path = shading.selected_studio_light().path();
if (b_v3d && b_v3d.shading().type() == BL::View3DShading::type_RENDERED) {
use_scene_world = b_v3d.shading().use_scene_world_render();
use_scene_lights = b_v3d.shading().use_scene_lights_render();
if (!use_scene_world) {
studiolight_rotate_z = b_v3d.shading().studiolight_rotate_z();
studiolight_intensity = b_v3d.shading().studiolight_intensity();
studiolight_background_alpha = b_v3d.shading().studiolight_background_alpha();
studiolight_path = b_v3d.shading().selected_studio_light().path();
}
}
}

View File

@@ -17,8 +17,6 @@
#ifdef WITH_OPTIX
# include "device/device.h"
# include "bvh/bvh_optix.h"
CCL_NAMESPACE_BEGIN
@@ -28,7 +26,6 @@ BVHOptiX::BVHOptiX(const BVHParams &params_,
const vector<Object *> &objects_,
Device *device)
: BVH(params_, geometry_, objects_),
device(device),
traversable_handle(0),
as_data(device, params_.top_level ? "optix tlas" : "optix blas", false),
motion_transform_data(device, "optix motion transform", false)
@@ -37,9 +34,7 @@ BVHOptiX::BVHOptiX(const BVHParams &params_,
BVHOptiX::~BVHOptiX()
{
// Acceleration structure memory is delayed freed on device, since deleting the
// BVH may happen while still being used for rendering.
device->release_optix_bvh(this);
// Acceleration structure memory is freed via the 'as_data' destructor
}
CCL_NAMESPACE_END

View File

@@ -28,7 +28,6 @@ CCL_NAMESPACE_BEGIN
class BVHOptiX : public BVH {
public:
Device *device;
uint64_t traversable_handle;
device_only_memory<char> as_data;
device_only_memory<char> motion_transform_data;

View File

@@ -61,6 +61,7 @@ enum DeviceTypeMask {
};
enum DeviceKernelStatus {
DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL = 0,
DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE,
DEVICE_KERNEL_USING_FEATURE_KERNEL,
DEVICE_KERNEL_FEATURE_KERNEL_INVALID,
@@ -426,9 +427,6 @@ class Device {
/* acceleration structure building */
virtual void build_bvh(BVH *bvh, Progress &progress, bool refit);
/* OptiX specific destructor. */
virtual void release_optix_bvh(BVH * /*bvh*/){};
#ifdef WITH_NETWORK
/* networking */
void server_run();

View File

@@ -35,54 +35,10 @@ device_memory::device_memory(Device *device, const char *name, MemoryType type)
device_pointer(0),
host_pointer(0),
shared_pointer(0),
shared_counter(0),
original_device_ptr(0),
original_device_size(0),
original_device(0),
need_realloc_(false),
modified(false)
shared_counter(0)
{
}
device_memory::device_memory(device_memory &&other) noexcept
: data_type(other.data_type),
data_elements(other.data_elements),
data_size(other.data_size),
device_size(other.device_size),
data_width(other.data_width),
data_height(other.data_height),
data_depth(other.data_depth),
type(other.type),
name(other.name),
device(other.device),
device_pointer(other.device_pointer),
host_pointer(other.host_pointer),
shared_pointer(other.shared_pointer),
shared_counter(other.shared_counter),
original_device_ptr(other.original_device_ptr),
original_device_size(other.original_device_size),
original_device(other.original_device),
need_realloc_(other.need_realloc_),
modified(other.modified)
{
other.data_elements = 0;
other.data_size = 0;
other.device_size = 0;
other.data_width = 0;
other.data_height = 0;
other.data_depth = 0;
other.device = 0;
other.device_pointer = 0;
other.host_pointer = 0;
other.shared_pointer = 0;
other.shared_counter = 0;
other.original_device_ptr = 0;
other.original_device_size = 0;
other.original_device = 0;
other.need_realloc_ = false;
other.modified = false;
}
device_memory::~device_memory()
{
assert(shared_pointer == 0);

View File

@@ -238,7 +238,6 @@ class device_memory {
/* Only create through subclasses. */
device_memory(Device *device, const char *name, MemoryType type);
device_memory(device_memory &&other) noexcept;
/* No copying allowed. */
device_memory(const device_memory &) = delete;
@@ -278,10 +277,6 @@ template<typename T> class device_only_memory : public device_memory {
data_elements = max(device_type_traits<T>::num_elements, 1);
}
device_only_memory(device_only_memory &&other) noexcept : device_memory(std::move(other))
{
}
virtual ~device_only_memory()
{
free();

View File

@@ -232,6 +232,10 @@ class MultiDevice : public Device {
foreach (SubDevice &sub, devices) {
DeviceKernelStatus subresult = sub.device->get_active_kernel_switch_state();
switch (subresult) {
case DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL:
result = subresult;
break;
case DEVICE_KERNEL_FEATURE_KERNEL_INVALID:
case DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE:
return subresult;

View File

@@ -193,9 +193,6 @@ class OptiXDevice : public CUDADevice {
device_only_memory<unsigned char> denoiser_state;
int denoiser_input_passes = 0;
vector<device_only_memory<char>> delayed_free_bvh_memory;
thread_mutex delayed_free_bvh_mutex;
public:
OptiXDevice(DeviceInfo &info_, Stats &stats_, Profiler &profiler_, bool background_)
: CUDADevice(info_, stats_, profiler_, background_),
@@ -261,8 +258,6 @@ class OptiXDevice : public CUDADevice {
// Make CUDA context current
const CUDAContextScope scope(cuContext);
free_bvh_memory_delayed();
sbt_data.free();
texture_info.free();
launch_params.free();
@@ -726,11 +721,7 @@ class OptiXDevice : public CUDADevice {
}
}
else if (task.type == DeviceTask::SHADER) {
// CUDA kernels are used when doing baking
if (optix_module == NULL)
CUDADevice::shader(task);
else
launch_shader_eval(task, thread_index);
launch_shader_eval(task, thread_index);
}
else if (task.type == DeviceTask::DENOISE_BUFFER) {
// Set up a single tile that covers the whole task and denoise it
@@ -1306,8 +1297,6 @@ class OptiXDevice : public CUDADevice {
return;
}
free_bvh_memory_delayed();
BVHOptiX *const bvh_optix = static_cast<BVHOptiX *>(bvh);
progress.set_substatus("Building OptiX acceleration structure");
@@ -1778,24 +1767,6 @@ class OptiXDevice : public CUDADevice {
}
}
void release_optix_bvh(BVH *bvh) override
{
thread_scoped_lock lock(delayed_free_bvh_mutex);
/* Do delayed free of BVH memory, since geometry holding BVH might be deleted
* while GPU is still rendering. */
BVHOptiX *const bvh_optix = static_cast<BVHOptiX *>(bvh);
delayed_free_bvh_memory.emplace_back(std::move(bvh_optix->as_data));
delayed_free_bvh_memory.emplace_back(std::move(bvh_optix->motion_transform_data));
bvh_optix->traversable_handle = 0;
}
void free_bvh_memory_delayed()
{
thread_scoped_lock lock(delayed_free_bvh_mutex);
delayed_free_bvh_memory.free_memory();
}
void const_copy_to(const char *name, void *host, size_t size) override
{
// Set constant memory for CUDA module

View File

@@ -269,6 +269,7 @@ class OpenCLDevice : public Device {
cl_device_id cdDevice;
cl_int ciErr;
int device_num;
bool use_preview_kernels;
class OpenCLProgram {
public:
@@ -368,7 +369,8 @@ class OpenCLDevice : public Device {
/* Load the kernels and put the created kernels in the given
* `programs` parameter. */
void load_kernels(vector<OpenCLProgram *> &programs,
const DeviceRequestedFeatures &requested_features);
const DeviceRequestedFeatures &requested_features,
bool is_preview = false);
};
DeviceSplitKernel *split_kernel;
@@ -380,6 +382,7 @@ class OpenCLDevice : public Device {
OpenCLProgram denoising_program;
OpenCLSplitPrograms kernel_programs;
OpenCLSplitPrograms preview_programs;
typedef map<string, device_vector<uchar> *> ConstMemMap;
typedef map<string, device_ptr> MemMap;
@@ -409,6 +412,7 @@ class OpenCLDevice : public Device {
string device_md5_hash(string kernel_custom_build_options = "");
bool load_kernels(const DeviceRequestedFeatures &requested_features);
void load_required_kernels(const DeviceRequestedFeatures &requested_features);
void load_preview_kernels();
bool wait_for_availability(const DeviceRequestedFeatures &requested_features);
DeviceKernelStatus get_active_kernel_switch_state();
@@ -418,7 +422,8 @@ class OpenCLDevice : public Device {
/* Get the program file name to compile (*.cl) for the given kernel */
const string get_opencl_program_filename(const string &kernel_name);
string get_build_options(const DeviceRequestedFeatures &requested_features,
const string &opencl_program_name);
const string &opencl_program_name,
bool preview_kernel = false);
/* Enable the default features to reduce recompilation events */
void enable_default_features(DeviceRequestedFeatures &features);

View File

@@ -107,7 +107,8 @@ void OpenCLDevice::enable_default_features(DeviceRequestedFeatures &features)
}
string OpenCLDevice::get_build_options(const DeviceRequestedFeatures &requested_features,
const string &opencl_program_name)
const string &opencl_program_name,
bool preview_kernel)
{
/* first check for non-split kernel programs */
if (opencl_program_name == "base" || opencl_program_name == "denoising") {
@@ -184,7 +185,13 @@ string OpenCLDevice::get_build_options(const DeviceRequestedFeatures &requested_
enable_default_features(nofeatures);
/* Add program specific optimized compile directives */
if (opencl_program_name == "split_do_volume" && !requested_features.use_volume) {
if (preview_kernel) {
DeviceRequestedFeatures preview_features;
preview_features.use_hair = true;
build_options += "-D__KERNEL_AO_PREVIEW__ ";
build_options += preview_features.get_build_options();
}
else if (opencl_program_name == "split_do_volume" && !requested_features.use_volume) {
build_options += nofeatures.get_build_options();
}
else {
@@ -231,7 +238,9 @@ OpenCLDevice::OpenCLSplitPrograms::~OpenCLSplitPrograms()
}
void OpenCLDevice::OpenCLSplitPrograms::load_kernels(
vector<OpenCLProgram *> &programs, const DeviceRequestedFeatures &requested_features)
vector<OpenCLProgram *> &programs,
const DeviceRequestedFeatures &requested_features,
bool is_preview)
{
if (!requested_features.use_baking) {
# define ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(kernel_name) \
@@ -242,7 +251,7 @@ void OpenCLDevice::OpenCLSplitPrograms::load_kernels(
device, \
program_name_##kernel_name, \
"kernel_" #kernel_name ".cl", \
device->get_build_options(requested_features, program_name_##kernel_name)); \
device->get_build_options(requested_features, program_name_##kernel_name, is_preview)); \
program_##kernel_name.add_kernel(ustring("path_trace_" #kernel_name)); \
programs.push_back(&program_##kernel_name);
@@ -250,7 +259,7 @@ void OpenCLDevice::OpenCLSplitPrograms::load_kernels(
ADD_SPLIT_KERNEL_PROGRAM(subsurface_scatter);
ADD_SPLIT_KERNEL_PROGRAM(direct_lighting);
ADD_SPLIT_KERNEL_PROGRAM(indirect_background);
if (requested_features.use_volume) {
if (requested_features.use_volume || is_preview) {
ADD_SPLIT_KERNEL_PROGRAM(do_volume);
}
ADD_SPLIT_KERNEL_PROGRAM(shader_eval);
@@ -265,7 +274,7 @@ void OpenCLDevice::OpenCLSplitPrograms::load_kernels(
device,
"split_bundle",
"kernel_split_bundle.cl",
device->get_build_options(requested_features, "split_bundle"));
device->get_build_options(requested_features, "split_bundle", is_preview));
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(data_init);
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(state_buffer_size);
@@ -394,7 +403,7 @@ class OpenCLSplitKernel : public DeviceSplitKernel {
device,
program_name,
device->get_opencl_program_filename(kernel_name),
device->get_build_options(requested_features, program_name));
device->get_build_options(requested_features, program_name, device->use_preview_kernels));
kernel->program.add_kernel(ustring("path_trace_" + kernel_name));
kernel->program.load();
@@ -560,11 +569,6 @@ class OpenCLSplitKernel : public DeviceSplitKernel {
size_t num_elements = max_elements_for_max_buffer_size(kg, data, max_buffer_size);
int2 global_size = make_int2(max(round_down((int)sqrt(num_elements), 64), 64),
(int)sqrt(num_elements));
if (device->info.description.find("Intel") != string::npos) {
global_size = make_int2(min(512, global_size.x), min(512, global_size.y));
}
VLOG(1) << "Global size: " << global_size << ".";
return global_size;
}
@@ -608,6 +612,7 @@ OpenCLDevice::OpenCLDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, b
: Device(info, stats, profiler, background),
load_kernel_num_compiling(0),
kernel_programs(this),
preview_programs(this),
memory_manager(this),
texture_info(this, "__texture_info", MEM_GLOBAL)
{
@@ -617,6 +622,7 @@ OpenCLDevice::OpenCLDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, b
cqCommandQueue = NULL;
device_initialized = false;
textures_need_update = true;
use_preview_kernels = !background;
vector<OpenCLPlatformDevice> usable_devices;
OpenCLInfo::get_usable_devices(&usable_devices);
@@ -672,6 +678,9 @@ OpenCLDevice::OpenCLDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, b
device_initialized = true;
split_kernel = new OpenCLSplitKernel(this);
if (use_preview_kernels) {
load_preview_kernels();
}
}
OpenCLDevice::~OpenCLDevice()
@@ -762,7 +771,7 @@ bool OpenCLDevice::load_kernels(const DeviceRequestedFeatures &requested_feature
load_required_kernels(requested_features);
vector<OpenCLProgram *> programs;
kernel_programs.load_kernels(programs, requested_features);
kernel_programs.load_kernels(programs, requested_features, false);
if (!requested_features.use_baking && requested_features.use_denoising) {
denoising_program = OpenCLProgram(
@@ -840,6 +849,19 @@ void OpenCLDevice::load_required_kernels(const DeviceRequestedFeatures &requeste
}
}
void OpenCLDevice::load_preview_kernels()
{
DeviceRequestedFeatures no_features;
vector<OpenCLProgram *> programs;
preview_programs.load_kernels(programs, no_features, true);
foreach (OpenCLProgram *program, programs) {
if (!program->load()) {
load_required_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
}
}
}
bool OpenCLDevice::wait_for_availability(const DeviceRequestedFeatures &requested_features)
{
if (requested_features.use_baking) {
@@ -847,18 +869,59 @@ bool OpenCLDevice::wait_for_availability(const DeviceRequestedFeatures &requeste
return true;
}
load_kernel_task_pool.wait_work();
if (background) {
load_kernel_task_pool.wait_work();
use_preview_kernels = false;
}
else {
/* We use a device setting to determine to load preview kernels or not
* Better to check on device level than per kernel as mixing preview and
* non-preview kernels does not work due to different data types */
if (use_preview_kernels) {
use_preview_kernels = load_kernel_num_compiling.load() > 0;
}
}
return split_kernel->load_kernels(requested_features);
}
OpenCLDevice::OpenCLSplitPrograms *OpenCLDevice::get_split_programs()
{
return &kernel_programs;
return use_preview_kernels ? &preview_programs : &kernel_programs;
}
DeviceKernelStatus OpenCLDevice::get_active_kernel_switch_state()
{
return DEVICE_KERNEL_USING_FEATURE_KERNEL;
/* Do not switch kernels for background renderings
* We do foreground rendering but use the preview kernels
* Check for the optimized kernels
*
* This works also the other way around, where we are using
* optimized kernels but new ones are being compiled due
* to other features that are needed */
if (background) {
/* The if-statements below would find the same result,
* But as the `finished` method uses a mutex we added
* this as an early exit */
return DEVICE_KERNEL_USING_FEATURE_KERNEL;
}
bool other_kernels_finished = load_kernel_num_compiling.load() == 0;
if (use_preview_kernels) {
if (other_kernels_finished) {
return DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE;
}
else {
return DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL;
}
}
else {
if (other_kernels_finished) {
return DEVICE_KERNEL_USING_FEATURE_KERNEL;
}
else {
return DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
}
}
}
void OpenCLDevice::mem_alloc(device_memory &mem)

View File

@@ -367,17 +367,9 @@ void Node::copy_value(const SocketType &socket, const Node &other, const SocketT
case SocketType::TRANSFORM_ARRAY:
copy_array<Transform>(this, socket, &other, other_socket);
break;
case SocketType::NODE_ARRAY: {
case SocketType::NODE_ARRAY:
copy_array<void *>(this, socket, &other, other_socket);
array<Node *> &node_array = get_socket_value<array<Node *>>(this, socket);
for (Node *node : node_array) {
node->reference();
}
break;
}
default:
assert(0);
break;
@@ -387,14 +379,6 @@ void Node::copy_value(const SocketType &socket, const Node &other, const SocketT
const void *src = ((char *)&other) + other_socket.struct_offset;
void *dst = ((char *)this) + socket.struct_offset;
memcpy(dst, src, socket.size());
if (socket.type == SocketType::NODE) {
Node *node = get_socket_value<Node *>(this, socket);
if (node) {
node->reference();
}
}
}
}
@@ -789,26 +773,6 @@ void Node::set_owner(const NodeOwner *owner_)
owner = owner_;
}
void Node::dereference_all_used_nodes()
{
foreach (const SocketType &socket, type->inputs) {
if (socket.type == SocketType::NODE) {
Node *node = get_socket_value<Node *>(this, socket);
if (node) {
node->dereference();
}
}
else if (socket.type == SocketType::NODE_ARRAY) {
const array<Node *> &nodes = get_socket_value<array<Node *>>(this, socket);
for (Node *node : nodes) {
node->dereference();
}
}
}
}
bool Node::socket_is_modified(const SocketType &input) const
{
return (socket_modified & input.modified_flag_bit) != 0;
@@ -839,25 +803,6 @@ template<typename T> void Node::set_if_different(const SocketType &input, T valu
socket_modified |= input.modified_flag_bit;
}
void Node::set_if_different(const SocketType &input, Node *value)
{
if (get_socket_value<Node *>(this, input) == value) {
return;
}
Node *old_node = get_socket_value<Node *>(this, input);
if (old_node) {
old_node->dereference();
}
if (value) {
value->reference();
}
get_socket_value<Node *>(this, input) = value;
socket_modified |= input.modified_flag_bit;
}
template<typename T> void Node::set_if_different(const SocketType &input, array<T> &value)
{
if (!socket_is_modified(input)) {
@@ -870,27 +815,6 @@ template<typename T> void Node::set_if_different(const SocketType &input, array<
socket_modified |= input.modified_flag_bit;
}
void Node::set_if_different(const SocketType &input, array<Node *> &value)
{
if (!socket_is_modified(input)) {
if (get_socket_value<array<Node *>>(this, input) == value) {
return;
}
}
array<Node *> &old_nodes = get_socket_value<array<Node *>>(this, input);
for (Node *old_node : old_nodes) {
old_node->dereference();
}
for (Node *new_node : value) {
new_node->reference();
}
get_socket_value<array<Node *>>(this, input).steal_data(value);
socket_modified |= input.modified_flag_bit;
}
void Node::print_modified_sockets() const
{
printf("Node : %s\n", name.c_str());

View File

@@ -177,32 +177,8 @@ struct Node {
const NodeOwner *get_owner() const;
void set_owner(const NodeOwner *owner_);
int reference_count() const
{
return ref_count;
}
void reference()
{
ref_count += 1;
}
void dereference()
{
ref_count -= 1;
}
/* Set the reference count to zero. This should only be called when we know for sure that the
* Node is not used by anyone else. For now, this is only the case when "deleting" shaders, as
* they are never actually deleted. */
void clear_reference_count()
{
ref_count = 0;
}
protected:
const NodeOwner *owner;
int ref_count{0};
template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket)
{
@@ -213,19 +189,7 @@ struct Node {
template<typename T> void set_if_different(const SocketType &input, T value);
/* Explicit overload for Node sockets so we can handle reference counting. The old Node is
* dereferenced, and the new one is referenced. */
void set_if_different(const SocketType &input, Node *value);
template<typename T> void set_if_different(const SocketType &input, array<T> &value);
/* Explicit overload for Node sockets so we can handle reference counting. The old Nodes are
* dereferenced, and the new ones are referenced. */
void set_if_different(const SocketType &input, array<Node *> &value);
/* Call this function in derived classes' destructors to ensure that used Nodes are dereferenced
* properly. */
void dereference_all_used_nodes();
};
CCL_NAMESPACE_END

View File

@@ -148,17 +148,16 @@ struct NodeType {
#define NODE_DECLARE \
static const NodeType *get_node_type(); \
template<typename T> static const NodeType *register_type(); \
static Node *create(const NodeType *type); \
static const NodeType *node_type;
static Node *create(const NodeType *type);
#define NODE_DEFINE(structname) \
const NodeType *structname::node_type = structname::register_type<structname>(); \
Node *structname::create(const NodeType *) \
{ \
return new structname(); \
} \
const NodeType *structname::get_node_type() \
{ \
static const NodeType *node_type = register_type<structname>(); \
return node_type; \
} \
template<typename T> const NodeType *structname::register_type()
@@ -170,8 +169,6 @@ struct NodeType {
#define NODE_ABSTRACT_DEFINE(structname) \
const NodeType *structname::get_node_base_type() \
{ \
/* Base types constructed in this getter to ensure correct initialization \
* order. Regular types are not so they are auto-registered for XML parsing. */ \
static const NodeType *node_base_type = register_base_type<structname>(); \
return node_base_type; \
} \

View File

@@ -57,24 +57,14 @@ ccl_device ccl_addr_space void *closure_alloc_extra(ShaderData *sd, int size)
ccl_device_inline ShaderClosure *bsdf_alloc(ShaderData *sd, int size, float3 weight)
{
kernel_assert(isfinite3_safe(weight));
ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
const float sample_weight = fabsf(average(weight));
if (sc == NULL)
return NULL;
/* Use comparison this way to help dealing with non-finite weight: if the average is not finite
* we will not allocate new closure. */
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
if (sc == NULL) {
return NULL;
}
sc->sample_weight = sample_weight;
return sc;
}
return NULL;
float sample_weight = fabsf(average(weight));
sc->sample_weight = sample_weight;
return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? sc : NULL;
}
#ifdef __OSL__
@@ -83,27 +73,17 @@ ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
float3 weight,
void *data)
{
kernel_assert(isfinite3_safe(weight));
ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
const float sample_weight = fabsf(average(weight));
if (!sc)
return NULL;
/* Use comparison this way to help dealing with non-finite weight: if the average is not finite
* we will not allocate new closure. */
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
if (!sc) {
return NULL;
}
memcpy((void *)sc, data, size);
memcpy((void *)sc, data, size);
sc->weight = weight;
sc->sample_weight = sample_weight;
return sc;
}
return NULL;
float sample_weight = fabsf(average(weight));
sc->weight = weight;
sc->sample_weight = sample_weight;
return (sample_weight >= CLOSURE_WEIGHT_CUTOFF) ? sc : NULL;
}
#endif

View File

@@ -200,12 +200,12 @@ ccl_device bool light_spread_clamp_area_light(const float3 P,
* uv coordinates. */
const float new_center_u = 0.5f * (min_u + max_u);
const float new_center_v = 0.5f * (min_v + max_v);
const float new_len_u = max_u - min_u;
const float new_len_v = max_v - min_v;
const float new_len_u = 0.5f * (max_u - min_u);
const float new_len_v = 0.5f * (max_v - min_v);
*lightP = *lightP + new_center_u * u + new_center_v * v;
*axisu = u * new_len_u;
*axisv = v * new_len_v;
*axisu = u * new_len_u * 2.0f;
*axisv = v * new_len_v * 2.0f;
return true;
}

View File

@@ -25,9 +25,8 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline float3
subsurface_scatter_eval(ShaderData *sd, const ShaderClosure *sc, float disk_r, float r, bool all)
{
/* This is the Veach one-sample model with balance heuristic, some pdf
* factors drop out when using balance heuristic weighting. For branched
* path tracing (all) we sample all closure and don't use MIS. */
/* this is the veach one-sample model with balance heuristic, some pdf
* factors drop out when using balance heuristic weighting */
float3 eval_sum = zero_float3();
float pdf_sum = 0.0f;
float sample_weight_inv = 0.0f;
@@ -66,30 +65,6 @@ subsurface_scatter_eval(ShaderData *sd, const ShaderClosure *sc, float disk_r, f
return (pdf_sum > 0.0f) ? eval_sum / pdf_sum : zero_float3();
}
ccl_device_inline float3 subsurface_scatter_walk_eval(ShaderData *sd,
const ShaderClosure *sc,
float3 throughput,
bool all)
{
/* This is the Veach one-sample model with balance heuristic, some pdf
* factors drop out when using balance heuristic weighting. For branched
* path tracing (all) we sample all closure and don't use MIS. */
if (!all) {
float bssrdf_weight = 0.0f;
float weight = sc->sample_weight;
for (int i = 0; i < sd->num_closure; i++) {
sc = &sd->closure[i];
if (CLOSURE_IS_BSSRDF(sc->type)) {
bssrdf_weight += sc->sample_weight;
}
}
throughput *= bssrdf_weight / weight;
}
return throughput;
}
/* replace closures with a single diffuse bsdf closure after scatter step */
ccl_device void subsurface_scatter_setup_diffuse_bsdf(
KernelGlobals *kg, ShaderData *sd, ClosureType type, float roughness, float3 weight, float3 N)
@@ -462,8 +437,7 @@ ccl_device_noinline
ccl_addr_space PathState *state,
const ShaderClosure *sc,
const float bssrdf_u,
const float bssrdf_v,
bool all)
const float bssrdf_v)
{
/* Sample diffuse surface scatter into the object. */
float3 D;
@@ -632,10 +606,10 @@ ccl_device_noinline
t = ray->t;
}
else if (bounce == 0) {
/* Restore original position if nothing was hit after the first bounce,
* without the ray_offset() that was added to avoid self-intersection.
* Otherwise if that offset is relatively large compared to the scattering
* radius, we never go back up high enough to exit the surface. */
/* Restore original position if nothing was hit after the first bounce.
* Otherwise if the ray_offset() to avoid self-intersection is relatively
* large compared to the scattering radius, we go never backup high enough
* to exit the surface. */
ray->P = sd->P;
}
@@ -695,7 +669,7 @@ ccl_device_noinline
/* TODO: gain back performance lost from merging with disk BSSRDF. We
* only need to return on hit so this indirect ray push/pop overhead
* is not actually needed, but it does keep the code simpler. */
ss_isect->weight[0] = subsurface_scatter_walk_eval(sd, sc, throughput, all);
ss_isect->weight[0] = throughput;
#ifdef __SPLIT_KERNEL__
ss_isect->ray = *ray;
#endif
@@ -717,7 +691,7 @@ ccl_device_inline int subsurface_scatter_multi_intersect(KernelGlobals *kg,
return subsurface_scatter_disk(kg, ss_isect, sd, sc, lcg_state, bssrdf_u, bssrdf_v, all);
}
else {
return subsurface_random_walk(kg, ss_isect, sd, state, sc, bssrdf_u, bssrdf_v, all);
return subsurface_random_walk(kg, ss_isect, sd, state, sc, bssrdf_u, bssrdf_v);
}
}

View File

@@ -99,23 +99,27 @@ CCL_NAMESPACE_BEGIN
#define __AO__
#define __PASSES__
#define __HAIR__
#define __SVM__
#define __EMISSION__
#define __HOLDOUT__
#define __MULTI_CLOSURE__
#define __TRANSPARENT_SHADOWS__
#define __BACKGROUND_MIS__
#define __LAMP_MIS__
#define __CAMERA_MOTION__
#define __OBJECT_MOTION__
#define __BAKING__
#define __PRINCIPLED__
#define __SUBSURFACE__
#define __VOLUME__
#define __VOLUME_SCATTER__
#define __CMJ__
#define __SHADOW_RECORD_ALL__
#define __BRANCHED_PATH__
/* Without these we get an AO render, used by OpenCL preview kernel. */
#ifndef __KERNEL_AO_PREVIEW__
# define __SVM__
# define __EMISSION__
# define __HOLDOUT__
# define __MULTI_CLOSURE__
# define __TRANSPARENT_SHADOWS__
# define __BACKGROUND_MIS__
# define __LAMP_MIS__
# define __CAMERA_MOTION__
# define __OBJECT_MOTION__
# define __BAKING__
# define __PRINCIPLED__
# define __SUBSURFACE__
# define __VOLUME__
# define __VOLUME_SCATTER__
# define __CMJ__
# define __SHADOW_RECORD_ALL__
# define __BRANCHED_PATH__
#endif
/* Device specific features */
#ifdef __KERNEL_CPU__

View File

@@ -25,7 +25,7 @@
* coordinates to act as a seed since the noise functions don't have seed values.
* A seed value is needed for generating distortion textures and color outputs.
* The offset's components are in the range [100, 200], not too high to cause
* bad precision and not too small to be noticeable. We use float seed because
* bad precision and not to small to be noticeable. We use float seed because
* OSL only support float hashes.
*/

View File

@@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
* coordinates to act as a seed since the noise functions don't have seed values.
* A seed value is needed for generating distortion textures and color outputs.
* The offset's components are in the range [100, 200], not too high to cause
* bad precision and not too small to be noticeable. We use float seed because
* bad precision and not to small to be noticeable. We use float seed because
* OSL only support float hashes.
*/

View File

@@ -370,13 +370,10 @@ ccl_device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack
if (direction_type == NODE_TANGENT_UVMAP) {
/* UV map */
if (desc.offset == ATTR_STD_NOT_FOUND) {
stack_store_float3(stack, tangent_offset, zero_float3());
return;
}
else {
if (desc.offset == ATTR_STD_NOT_FOUND)
tangent = make_float3(0.0f, 0.0f, 0.0f);
else
tangent = attribute_value;
}
}
else {
/* radial */

View File

@@ -24,7 +24,6 @@ set(INC_SYS
set(SRC
alembic.cpp
alembic_read.cpp
attribute.cpp
background.cpp
bake.cpp
@@ -68,7 +67,6 @@ set(SRC
set(SRC_HEADERS
alembic.h
alembic_read.h
attribute.h
bake.h
background.h

File diff suppressed because it is too large Load Diff

View File

@@ -152,10 +152,6 @@ template<typename T> class DataStore {
double last_loaded_time = std::numeric_limits<double>::max();
public:
/* Keys used to compare values. */
Alembic::AbcCoreAbstract::ArraySample::Key key1;
Alembic::AbcCoreAbstract::ArraySample::Key key2;
void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling_)
{
time_sampling = time_sampling_;
@@ -229,11 +225,6 @@ template<typename T> class DataStore {
index_data_map.push_back({time, data_index.source_time, data_index.index});
}
void add_no_data(double time)
{
index_data_map.push_back({time, time, -1ul});
}
bool is_constant() const
{
return data.size() <= 1;
@@ -293,7 +284,7 @@ struct CachedData {
DataStore<array<int3>> triangles{};
/* triangle "loops" are the polygons' vertices indices used for indexing face varying attributes
* (like UVs) */
DataStore<array<int>> uv_loops{};
DataStore<array<int3>> triangles_loops{};
DataStore<array<int>> shader{};
/* subd data */
@@ -371,18 +362,16 @@ class AlembicObject : public Node {
void set_object(Object *object);
Object *get_object();
void load_data_in_cache(CachedData &cached_data,
AlembicProcedural *proc,
Alembic::AbcGeom::IPolyMeshSchema &schema,
Progress &progress);
void load_data_in_cache(CachedData &cached_data,
AlembicProcedural *proc,
Alembic::AbcGeom::ISubDSchema &schema,
Progress &progress);
void load_data_in_cache(CachedData &cached_data,
AlembicProcedural *proc,
const Alembic::AbcGeom::ICurvesSchema &schema,
Progress &progress);
void load_all_data(AlembicProcedural *proc,
Alembic::AbcGeom::IPolyMeshSchema &schema,
Progress &progress);
void load_all_data(AlembicProcedural *proc,
Alembic::AbcGeom::ISubDSchema &schema,
Progress &progress);
void load_all_data(AlembicProcedural *proc,
const Alembic::AbcGeom::ICurvesSchema &schema,
Progress &progress,
float default_radius);
bool has_data_loaded() const;
@@ -408,21 +397,33 @@ class AlembicObject : public Node {
CachedData &get_cached_data()
{
return cached_data_;
return cached_data;
}
bool is_constant() const
{
return cached_data_.is_constant();
return cached_data.is_constant();
}
Object *object = nullptr;
bool data_loaded = false;
CachedData cached_data_;
CachedData cached_data;
void setup_transform_cache(CachedData &cached_data, float scale);
void update_shader_attributes(const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
Progress &progress);
void read_attribute(const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
const ustring &attr_name,
Progress &progress);
template<typename SchemaType>
void read_face_sets(SchemaType &schema,
array<int> &polygon_to_shader,
Alembic::AbcGeom::ISampleSelector sample_sel);
void setup_transform_cache(float scale);
AttributeRequestSet get_requested_attributes();
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,134 +0,0 @@
/*
* Copyright 2021 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#ifdef WITH_ALEMBIC
# include <Alembic/AbcCoreFactory/All.h>
# include <Alembic/AbcGeom/All.h>
# include "util/util_vector.h"
CCL_NAMESPACE_BEGIN
class AlembicProcedural;
class AttributeRequestSet;
class Progress;
struct CachedData;
/* Maps a FaceSet whose name matches that of a Shader to the index of said shader in the Geometry's
* used_shaders list. */
struct FaceSetShaderIndexPair {
Alembic::AbcGeom::IFaceSet face_set;
int shader_index;
};
/* Data of an IPolyMeshSchema that we need to read. */
struct PolyMeshSchemaData {
Alembic::AbcGeom::TimeSamplingPtr time_sampling;
size_t num_samples;
Alembic::AbcGeom::MeshTopologyVariance topology_variance;
Alembic::AbcGeom::IP3fArrayProperty positions;
Alembic::AbcGeom::IInt32ArrayProperty face_indices;
Alembic::AbcGeom::IInt32ArrayProperty face_counts;
Alembic::AbcGeom::IN3fGeomParam normals;
vector<FaceSetShaderIndexPair> shader_face_sets;
// Unsupported for now.
Alembic::AbcGeom::IV3fArrayProperty velocities;
};
void read_geometry_data(AlembicProcedural *proc,
CachedData &cached_data,
const PolyMeshSchemaData &data,
Progress &progress);
/* Data of an ISubDSchema that we need to read. */
struct SubDSchemaData {
Alembic::AbcGeom::TimeSamplingPtr time_sampling;
size_t num_samples;
Alembic::AbcGeom::MeshTopologyVariance topology_variance;
Alembic::AbcGeom::IInt32ArrayProperty face_counts;
Alembic::AbcGeom::IInt32ArrayProperty face_indices;
Alembic::AbcGeom::IP3fArrayProperty positions;
Alembic::AbcGeom::IInt32ArrayProperty crease_indices;
Alembic::AbcGeom::IInt32ArrayProperty crease_lengths;
Alembic::AbcGeom::IFloatArrayProperty crease_sharpnesses;
vector<FaceSetShaderIndexPair> shader_face_sets;
// Those are unsupported for now.
Alembic::AbcGeom::IInt32ArrayProperty corner_indices;
Alembic::AbcGeom::IFloatArrayProperty corner_sharpnesses;
Alembic::AbcGeom::IInt32Property face_varying_interpolate_boundary;
Alembic::AbcGeom::IInt32Property face_varying_propagate_corners;
Alembic::AbcGeom::IInt32Property interpolate_boundary;
Alembic::AbcGeom::IInt32ArrayProperty holes;
Alembic::AbcGeom::IStringProperty subdivision_scheme;
Alembic::AbcGeom::IV3fArrayProperty velocities;
};
void read_geometry_data(AlembicProcedural *proc,
CachedData &cached_data,
const SubDSchemaData &data,
Progress &progress);
/* Data of a ICurvesSchema that we need to read. */
struct CurvesSchemaData {
Alembic::AbcGeom::TimeSamplingPtr time_sampling;
size_t num_samples;
Alembic::AbcGeom::MeshTopologyVariance topology_variance;
Alembic::AbcGeom::IP3fArrayProperty positions;
Alembic::AbcGeom::IInt32ArrayProperty num_vertices;
float default_radius;
float radius_scale;
// Those are unsupported for now.
Alembic::AbcGeom::IV3fArrayProperty velocities;
// if this property is invalid then the weight for every point is 1
Alembic::AbcGeom::IFloatArrayProperty position_weights;
Alembic::AbcGeom::IN3fGeomParam normals;
Alembic::AbcGeom::IFloatGeomParam widths;
Alembic::AbcGeom::IUcharArrayProperty orders;
Alembic::AbcGeom::IFloatArrayProperty knots;
// TODO(@kevindietrich): type, basis, wrap
};
void read_geometry_data(AlembicProcedural *proc,
CachedData &cached_data,
const CurvesSchemaData &data,
Progress &progress);
void read_attributes(AlembicProcedural *proc,
CachedData &cache,
const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
const Alembic::AbcGeom::IV2fGeomParam &default_uvs_param,
const AttributeRequestSet &requested_attributes,
Progress &progress);
CCL_NAMESPACE_END
#endif

View File

@@ -383,23 +383,6 @@ AttributeStandard Attribute::name_standard(const char *name)
return ATTR_STD_NONE;
}
AttrKernelDataType Attribute::kernel_type(const Attribute &attr)
{
if (attr.element == ATTR_ELEMENT_CORNER) {
return AttrKernelDataType::UCHAR4;
}
if (attr.type == TypeDesc::TypeFloat) {
return AttrKernelDataType::FLOAT;
}
if (attr.type == TypeFloat2) {
return AttrKernelDataType::FLOAT2;
}
return AttrKernelDataType::FLOAT3;
}
void Attribute::get_uv_tiles(Geometry *geom,
AttributePrimitive prim,
unordered_set<int> &tiles) const
@@ -434,7 +417,7 @@ void Attribute::get_uv_tiles(Geometry *geom,
/* Attribute Set */
AttributeSet::AttributeSet(Geometry *geometry, AttributePrimitive prim)
: modified_flag(~0u), geometry(geometry), prim(prim)
: geometry(geometry), prim(prim)
{
}
@@ -457,7 +440,7 @@ Attribute *AttributeSet::add(ustring name, TypeDesc type, AttributeElement eleme
Attribute new_attr(name, type, element, geometry, prim);
attributes.emplace_back(std::move(new_attr));
tag_modified(attributes.back());
modified = true;
return &attributes.back();
}
@@ -479,7 +462,8 @@ void AttributeSet::remove(ustring name)
for (it = attributes.begin(); it != attributes.end(); it++) {
if (&*it == attr) {
remove(it);
modified = true;
attributes.erase(it);
return;
}
}
@@ -624,7 +608,8 @@ void AttributeSet::remove(AttributeStandard std)
for (it = attributes.begin(); it != attributes.end(); it++) {
if (&*it == attr) {
remove(it);
modified = true;
attributes.erase(it);
return;
}
}
@@ -649,12 +634,6 @@ void AttributeSet::remove(Attribute *attribute)
}
}
void AttributeSet::remove(list<Attribute>::iterator it)
{
tag_modified(*it);
attributes.erase(it);
}
void AttributeSet::resize(bool reserve_only)
{
foreach (Attribute &attr, attributes) {
@@ -695,22 +674,21 @@ void AttributeSet::update(AttributeSet &&new_attributes)
for (it = attributes.begin(); it != attributes.end();) {
if (it->std != ATTR_STD_NONE) {
if (new_attributes.find(it->std) == nullptr) {
remove(it++);
modified = true;
attributes.erase(it++);
continue;
}
}
else if (it->name != "") {
if (new_attributes.find(it->name) == nullptr) {
remove(it++);
modified = true;
attributes.erase(it++);
continue;
}
}
it++;
}
/* If all attributes were replaced, transform is no longer applied. */
geometry->transform_applied = false;
}
void AttributeSet::clear_modified()
@@ -718,27 +696,7 @@ void AttributeSet::clear_modified()
foreach (Attribute &attr, attributes) {
attr.modified = false;
}
modified_flag = 0;
}
void AttributeSet::tag_modified(const Attribute &attr)
{
/* Some attributes are not stored in the various kernel attribute arrays
* (DeviceScene::attribute_*), so the modified flags are only set if the associated standard
* corresponds to an attribute which will be stored in the kernel's attribute arrays. */
const bool modifies_device_array = (attr.std != ATTR_STD_FACE_NORMAL &&
attr.std != ATTR_STD_VERTEX_NORMAL);
if (modifies_device_array) {
AttrKernelDataType kernel_type = Attribute::kernel_type(attr);
modified_flag |= (1u << kernel_type);
}
}
bool AttributeSet::modified(AttrKernelDataType kernel_type) const
{
return (modified_flag & (1u << kernel_type)) != 0;
modified = false;
}
/* AttributeRequest */

View File

@@ -39,21 +39,6 @@ class Hair;
class Mesh;
struct Transform;
/* AttrKernelDataType.
*
* The data type of the device arrays storing the attribute's data. Those data types are different
* than the ones for attributes as some attribute types are stored in the same array, e.g. Point,
* Vector, and Transform are all stored as float3 in the kernel.
*
* The values of this enumeration are also used as flags to detect changes in AttributeSet. */
enum AttrKernelDataType {
FLOAT = 0,
FLOAT2 = 1,
FLOAT3 = 2,
UCHAR4 = 3,
};
/* Attribute
*
* Arbitrary data layers on meshes.
@@ -182,8 +167,6 @@ class Attribute {
static const char *standard_name(AttributeStandard std);
static AttributeStandard name_standard(const char *name);
static AttrKernelDataType kernel_type(const Attribute &attr);
void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set<int> &tiles) const;
};
@@ -192,12 +175,11 @@ class Attribute {
* Set of attributes on a mesh. */
class AttributeSet {
uint32_t modified_flag;
public:
Geometry *geometry;
AttributePrimitive prim;
list<Attribute> attributes;
bool modified = true;
AttributeSet(Geometry *geometry, AttributePrimitive prim);
AttributeSet(AttributeSet &&) = default;
@@ -215,8 +197,6 @@ class AttributeSet {
void remove(Attribute *attribute);
void remove(list<Attribute>::iterator it);
void resize(bool reserve_only = false);
void clear(bool preserve_voxel_data = false);
@@ -224,18 +204,7 @@ class AttributeSet {
* and remove any attribute not found on the new set from this. */
void update(AttributeSet &&new_attributes);
/* Return whether the attributes of the given kernel_type are modified, where "modified" means
* that some attributes of the given type were added or removed from this AttributeSet. This does
* not mean that the data of the remaining attributes in this AttributeSet were also modified. To
* check this, use Attribute.modified. */
bool modified(AttrKernelDataType kernel_type) const;
void clear_modified();
private:
/* Set the relevant modified flag for the attribute. Only attributes that are stored in device
* arrays will be considered for tagging this AttributeSet as modified. */
void tag_modified(const Attribute &attr);
};
/* AttributeRequest

View File

@@ -59,7 +59,6 @@ Background::Background() : Node(get_node_type())
Background::~Background()
{
dereference_all_used_nodes();
}
void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene)

View File

@@ -46,12 +46,6 @@ CCL_NAMESPACE_BEGIN
/* Geometry */
PackFlags operator|=(PackFlags &pack_flags, uint32_t value)
{
pack_flags = (PackFlags)((uint32_t)pack_flags | value);
return pack_flags;
}
NODE_ABSTRACT_DEFINE(Geometry)
{
NodeType *type = NodeType::add("geometry_base", NULL);
@@ -85,7 +79,6 @@ Geometry::Geometry(const NodeType *node_type, const Type type)
Geometry::~Geometry()
{
dereference_all_used_nodes();
delete bvh;
}
@@ -830,13 +823,10 @@ void GeometryManager::device_update_attributes(Device *device,
dscene->attributes_float3.alloc(attr_float3_size);
dscene->attributes_uchar4.alloc(attr_uchar4_size);
/* The order of those flags needs to match that of AttrKernelDataType. */
const bool attributes_need_realloc[4] = {
dscene->attributes_float.need_realloc(),
dscene->attributes_float2.need_realloc(),
dscene->attributes_float3.need_realloc(),
dscene->attributes_uchar4.need_realloc(),
};
const bool copy_all_data = dscene->attributes_float.need_realloc() ||
dscene->attributes_float2.need_realloc() ||
dscene->attributes_float3.need_realloc() ||
dscene->attributes_uchar4.need_realloc();
size_t attr_float_offset = 0;
size_t attr_float2_offset = 0;
@@ -855,7 +845,7 @@ void GeometryManager::device_update_attributes(Device *device,
if (attr) {
/* force a copy if we need to reallocate all the data */
attr->modified |= attributes_need_realloc[Attribute::kernel_type(*attr)];
attr->modified |= copy_all_data;
}
update_attribute_element_offset(geom,
@@ -878,7 +868,7 @@ void GeometryManager::device_update_attributes(Device *device,
if (subd_attr) {
/* force a copy if we need to reallocate all the data */
subd_attr->modified |= attributes_need_realloc[Attribute::kernel_type(*subd_attr)];
subd_attr->modified |= copy_all_data;
}
update_attribute_element_offset(mesh,
@@ -909,10 +899,6 @@ void GeometryManager::device_update_attributes(Device *device,
foreach (AttributeRequest &req, attributes.requests) {
Attribute *attr = values.find(req);
if (attr) {
attr->modified |= attributes_need_realloc[Attribute::kernel_type(*attr)];
}
update_attribute_element_offset(object->geometry,
dscene->attributes_float,
attr_float_offset,
@@ -948,10 +934,10 @@ void GeometryManager::device_update_attributes(Device *device,
/* copy to device */
progress.set_status("Updating Mesh", "Copying Attributes to device");
dscene->attributes_float.copy_to_device_if_modified();
dscene->attributes_float2.copy_to_device_if_modified();
dscene->attributes_float3.copy_to_device_if_modified();
dscene->attributes_uchar4.copy_to_device_if_modified();
dscene->attributes_float.copy_to_device();
dscene->attributes_float2.copy_to_device();
dscene->attributes_float3.copy_to_device();
dscene->attributes_uchar4.copy_to_device();
if (progress.get_cancel())
return;
@@ -1249,16 +1235,7 @@ void GeometryManager::device_update_bvh(Device *device,
const bool can_refit = scene->bvh != nullptr &&
(bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX);
PackFlags pack_flags = PackFlags::PACK_NONE;
if (scene->bvh == nullptr) {
pack_flags |= PackFlags::PACK_ALL;
}
if (dscene->prim_visibility.is_modified()) {
pack_flags |= PackFlags::PACK_VISIBILITY;
}
const bool pack_all = scene->bvh == nullptr;
BVH *bvh = scene->bvh;
if (!scene->bvh) {
@@ -1296,14 +1273,10 @@ void GeometryManager::device_update_bvh(Device *device,
pack.root_index = -1;
if (pack_flags != PackFlags::PACK_ALL) {
if (!pack_all) {
/* if we do not need to recreate the BVH, then only the vertices are updated, so we can
* safely retake the memory */
dscene->prim_tri_verts.give_data(pack.prim_tri_verts);
if ((pack_flags & PackFlags::PACK_VISIBILITY) != 0) {
dscene->prim_visibility.give_data(pack.prim_visibility);
}
}
else {
/* It is not strictly necessary to skip those resizes we if do not have to repack, as the OS
@@ -1332,21 +1305,13 @@ void GeometryManager::device_update_bvh(Device *device,
// Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated
// based on that list, which may be ordered differently from the object list.
foreach (Geometry *geom, scene->geometry) {
/* Make a copy of the pack_flags so the current geometry's flags do not pollute the others'.
*/
PackFlags geom_pack_flags = pack_flags;
if (geom->is_modified()) {
geom_pack_flags |= PackFlags::PACK_VERTICES;
}
if (geom_pack_flags == PACK_NONE) {
if (!pack_all && !geom->is_modified()) {
continue;
}
const pair<int, uint> &info = geometry_to_object_info[geom];
pool.push(function_bind(
&Geometry::pack_primitives, geom, &pack, info.first, info.second, geom_pack_flags));
&Geometry::pack_primitives, geom, &pack, info.first, info.second, pack_all));
}
pool.wait_work();
}
@@ -1381,7 +1346,7 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->prim_type.steal_data(pack.prim_type);
dscene->prim_type.copy_to_device();
}
if (pack.prim_visibility.size() && (dscene->prim_visibility.is_modified() || has_bvh2_layout)) {
if (pack.prim_visibility.size() && (dscene->prim_visibility.need_realloc() || has_bvh2_layout)) {
dscene->prim_visibility.steal_data(pack.prim_visibility);
dscene->prim_visibility.copy_to_device();
}
@@ -1438,43 +1403,21 @@ static void update_device_flags_attribute(uint32_t &device_update_flags,
continue;
}
AttrKernelDataType kernel_type = Attribute::kernel_type(attr);
switch (kernel_type) {
case AttrKernelDataType::FLOAT: {
device_update_flags |= ATTR_FLOAT_MODIFIED;
break;
}
case AttrKernelDataType::FLOAT2: {
device_update_flags |= ATTR_FLOAT2_MODIFIED;
break;
}
case AttrKernelDataType::FLOAT3: {
device_update_flags |= ATTR_FLOAT3_MODIFIED;
break;
}
case AttrKernelDataType::UCHAR4: {
device_update_flags |= ATTR_UCHAR4_MODIFIED;
break;
}
if (attr.element == ATTR_ELEMENT_CORNER) {
device_update_flags |= ATTR_UCHAR4_MODIFIED;
}
else if (attr.type == TypeDesc::TypeFloat) {
device_update_flags |= ATTR_FLOAT_MODIFIED;
}
else if (attr.type == TypeFloat2) {
device_update_flags |= ATTR_FLOAT2_MODIFIED;
}
else if (attr.type == TypeDesc::TypeMatrix) {
device_update_flags |= ATTR_FLOAT3_MODIFIED;
}
else if (attr.element != ATTR_ELEMENT_VOXEL) {
device_update_flags |= ATTR_FLOAT3_MODIFIED;
}
}
}
static void update_attribute_realloc_flags(uint32_t &device_update_flags,
const AttributeSet &attributes)
{
if (attributes.modified(AttrKernelDataType::FLOAT)) {
device_update_flags |= ATTR_FLOAT_NEEDS_REALLOC;
}
if (attributes.modified(AttrKernelDataType::FLOAT2)) {
device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
}
if (attributes.modified(AttrKernelDataType::FLOAT3)) {
device_update_flags |= ATTR_FLOAT3_NEEDS_REALLOC;
}
if (attributes.modified(AttrKernelDataType::UCHAR4)) {
device_update_flags |= ATTR_UCHAR4_NEEDS_REALLOC;
}
}
@@ -1500,11 +1443,16 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
foreach (Geometry *geom, scene->geometry) {
geom->has_volume = false;
update_attribute_realloc_flags(device_update_flags, geom->attributes);
if (geom->attributes.modified) {
device_update_flags |= ATTRS_NEED_REALLOC;
}
if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
update_attribute_realloc_flags(device_update_flags, mesh->subd_attributes);
if (mesh->subd_attributes.modified) {
device_update_flags |= ATTRS_NEED_REALLOC;
}
}
foreach (Node *node, geom->get_used_shaders()) {
@@ -1646,10 +1594,6 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
}
}
if ((update_flags & VISIBILITY_MODIFIED) != 0) {
dscene->prim_visibility.tag_modified();
}
if (device_update_flags & ATTR_FLOAT_NEEDS_REALLOC) {
dscene->attributes_map.tag_realloc();
dscene->attributes_float.tag_realloc();
@@ -1976,8 +1920,7 @@ void GeometryManager::device_update(Device *device,
* Also update the BVH if the transformations change, we cannot rely on tagging the Geometry
* as modified in this case, as we may accumulate displacement if the vertices do not also
* change. */
bool need_update_scene_bvh = (scene->bvh == nullptr ||
(update_flags & (TRANSFORM_MODIFIED | VISIBILITY_MODIFIED)) != 0);
bool need_update_scene_bvh = (scene->bvh == nullptr || (update_flags & TRANSFORM_MODIFIED) != 0);
{
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {

View File

@@ -43,24 +43,6 @@ class Shader;
class Volume;
struct PackedBVH;
/* Flags used to determine which geometry data need to be packed. */
enum PackFlags : uint32_t {
PACK_NONE = 0u,
/* Pack the geometry information (e.g. triangle or curve keys indices). */
PACK_GEOMETRY = (1u << 0),
/* Pack the vertices, for Meshes and Volumes' bounding meshes. */
PACK_VERTICES = (1u << 1),
/* Pack the visibility flags for each triangle or curve. */
PACK_VISIBILITY = (1u << 2),
PACK_ALL = (PACK_GEOMETRY | PACK_VERTICES | PACK_VISIBILITY),
};
PackFlags operator|=(PackFlags &pack_flags, uint32_t value);
/* Geometry
*
* Base class for geometric types like Mesh and Hair. */
@@ -144,10 +126,7 @@ class Geometry : public Node {
int n,
int total);
virtual void pack_primitives(PackedBVH *pack,
int object,
uint visibility,
PackFlags pack_flags) = 0;
virtual void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) = 0;
/* Check whether the geometry should have own BVH built separately. Briefly,
* own BVH is needed for geometry, if:
@@ -212,8 +191,6 @@ class GeometryManager {
TRANSFORM_MODIFIED = (1 << 10),
VISIBILITY_MODIFIED = (1 << 11),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,

View File

@@ -494,47 +494,38 @@ void Hair::pack_curves(Scene *scene,
}
}
void Hair::pack_primitives(PackedBVH *pack, int object, uint visibility, PackFlags pack_flags)
void Hair::pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all)
{
if (curve_first_key.empty())
return;
/* Separate loop as other arrays are not initialized if their packing is not required. */
if ((pack_flags & PACK_VISIBILITY) != 0) {
unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
size_t index = 0;
for (size_t j = 0; j < num_curves(); ++j) {
Curve curve = get_curve(j);
for (size_t k = 0; k < curve.num_segments(); ++k, ++index) {
prim_visibility[index] = visibility;
}
}
/* If the BVH does not have to be recreated, we can bail out. */
if (!pack_all) {
return;
}
if ((pack_flags & PACK_GEOMETRY) != 0) {
unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
int *prim_type = &pack->prim_type[optix_prim_offset];
int *prim_index = &pack->prim_index[optix_prim_offset];
int *prim_object = &pack->prim_object[optix_prim_offset];
// 'pack->prim_time' is unused by Embree and OptiX
unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
int *prim_type = &pack->prim_type[optix_prim_offset];
unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
int *prim_index = &pack->prim_index[optix_prim_offset];
int *prim_object = &pack->prim_object[optix_prim_offset];
// 'pack->prim_time' is unused by Embree and OptiX
uint type = has_motion_blur() ?
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
PRIMITIVE_MOTION_CURVE_THICK) :
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON :
PRIMITIVE_CURVE_THICK);
uint type = has_motion_blur() ?
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
PRIMITIVE_MOTION_CURVE_THICK) :
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK);
size_t index = 0;
for (size_t j = 0; j < num_curves(); ++j) {
Curve curve = get_curve(j);
for (size_t k = 0; k < curve.num_segments(); ++k, ++index) {
prim_tri_index[index] = -1;
prim_type[index] = PRIMITIVE_PACK_SEGMENT(type, k);
// Each curve segment points back to its curve index
prim_index[index] = j + prim_offset;
prim_object[index] = object;
}
size_t index = 0;
for (size_t j = 0; j < num_curves(); ++j) {
Curve curve = get_curve(j);
for (size_t k = 0; k < curve.num_segments(); ++k, ++index) {
prim_tri_index[index] = -1;
prim_type[index] = PRIMITIVE_PACK_SEGMENT(type, k);
prim_visibility[index] = visibility;
// Each curve segment points back to its curve index
prim_index[index] = j + prim_offset;
prim_object[index] = object;
}
}
}

View File

@@ -146,10 +146,7 @@ class Hair : public Geometry {
/* BVH */
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
void pack_primitives(PackedBVH *pack,
int object,
uint visibility,
PackFlags pack_flags) override;
void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) override;
};
CCL_NAMESPACE_END

View File

@@ -159,7 +159,6 @@ NODE_DEFINE(Light)
Light::Light() : Node(get_node_type())
{
dereference_all_used_nodes();
}
void Light::tag_update(Scene *scene)
@@ -865,7 +864,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
const float min_spread_angle = 1.0f * M_PI_F / 180.0f;
const float spread_angle = 0.5f * (M_PI_F - max(light->spread, min_spread_angle));
/* Normalization computed using:
* integrate cos(x) * (1 - tan(x) * tan(a)) * sin(x) from x = 0 to pi/2 - a. */
* integrate cos(x) (1 - tan(x) * tan(a)) * sin(x) from x = a to pi/2. */
const float tan_spread = tanf(spread_angle);
const float normalize_spread = 2.0f / (2.0f + (2.0f * spread_angle - M_PI_F) * tan_spread);

View File

@@ -805,7 +805,7 @@ void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, ui
}
}
void Mesh::pack_primitives(ccl::PackedBVH *pack, int object, uint visibility, PackFlags pack_flags)
void Mesh::pack_primitives(ccl::PackedBVH *pack, int object, uint visibility, bool pack_all)
{
if (triangles.empty())
return;
@@ -819,38 +819,28 @@ void Mesh::pack_primitives(ccl::PackedBVH *pack, int object, uint visibility, Pa
uint type = has_motion_blur() ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE;
/* Separate loop as other arrays are not initialized if their packing is not required. */
if ((pack_flags & PackFlags::PACK_VISIBILITY) != 0) {
unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
for (size_t k = 0; k < num_prims; ++k) {
prim_visibility[k] = visibility;
}
}
if ((pack_flags & PackFlags::PACK_GEOMETRY) != 0) {
if (pack_all) {
/* Use optix_prim_offset for indexing as those arrays also contain data for Hair geometries. */
unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
int *prim_type = &pack->prim_type[optix_prim_offset];
unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
int *prim_index = &pack->prim_index[optix_prim_offset];
int *prim_object = &pack->prim_object[optix_prim_offset];
for (size_t k = 0; k < num_prims; ++k) {
if ((pack_flags & PackFlags::PACK_GEOMETRY) != 0) {
prim_tri_index[k] = (prim_offset + k) * 3;
prim_type[k] = type;
prim_index[k] = prim_offset + k;
prim_object[k] = object;
}
prim_tri_index[k] = (prim_offset + k) * 3;
prim_type[k] = type;
prim_index[k] = prim_offset + k;
prim_object[k] = object;
prim_visibility[k] = visibility;
}
}
if ((pack_flags & PackFlags::PACK_VERTICES) != 0) {
for (size_t k = 0; k < num_prims; ++k) {
const Mesh::Triangle t = get_triangle(k);
prim_tri_verts[k * 3] = float3_to_float4(verts[t.v[0]]);
prim_tri_verts[k * 3 + 1] = float3_to_float4(verts[t.v[1]]);
prim_tri_verts[k * 3 + 2] = float3_to_float4(verts[t.v[2]]);
}
for (size_t k = 0; k < num_prims; ++k) {
const Mesh::Triangle t = get_triangle(k);
prim_tri_verts[k * 3] = float3_to_float4(verts[t.v[0]]);
prim_tri_verts[k * 3 + 1] = float3_to_float4(verts[t.v[1]]);
prim_tri_verts[k * 3 + 2] = float3_to_float4(verts[t.v[2]]);
}
}

View File

@@ -232,10 +232,7 @@ class Mesh : public Geometry {
size_t tri_offset);
void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
void pack_primitives(PackedBVH *pack,
int object,
uint visibility,
PackFlags pack_flags) override;
void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) override;
void tessellate(DiagSplit *split);

View File

@@ -1600,23 +1600,11 @@ class SetNormalNode : public ShaderNode {
NODE_SOCKET_API(float3, direction)
};
class OSLNode final : public ShaderNode {
class OSLNode : public ShaderNode {
public:
static OSLNode *create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from = NULL);
~OSLNode();
static void operator delete(void *ptr)
{
/* Override delete operator to silence new-delete-type-mismatch ASAN warnings
* regarding size mismatch in the destructor. This is intentional as we allocate
* extra space at the end of the node. */
::operator delete(ptr);
}
static void operator delete(void *, void *)
{
/* Deliberately empty placement delete operator, to avoid MSVC warning C4291. */
}
ShaderNode *clone(ShaderGraph *graph) const;
char *input_default_value();

View File

@@ -220,10 +220,6 @@ void Object::tag_update(Scene *scene)
flag |= ObjectManager::TRANSFORM_MODIFIED;
}
if (visibility_is_modified()) {
flag |= ObjectManager::VISIBILITY_MODIFIED;
}
foreach (Node *node, geometry->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
if (shader->get_use_mis() && shader->has_surface_emission)
@@ -918,10 +914,6 @@ void ObjectManager::tag_update(Scene *scene, uint32_t flag)
geometry_flag |= GeometryManager::TRANSFORM_MODIFIED;
}
if ((flag & VISIBILITY_MODIFIED) != 0) {
geometry_flag |= GeometryManager::VISIBILITY_MODIFIED;
}
scene->geometry_manager->tag_update(scene, geometry_flag);
}

View File

@@ -134,7 +134,6 @@ class ObjectManager {
OBJECT_MODIFIED = (1 << 5),
HOLDOUT_MODIFIED = (1 << 6),
TRANSFORM_MODIFIED = (1 << 7),
VISIBILITY_MODIFIED = (1 << 8),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,

View File

@@ -91,10 +91,10 @@ void OSLShaderManager::reset(Scene * /*scene*/)
shading_system_init();
}
void OSLShaderManager::device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
void OSLShaderManager::device_update(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
{
if (!need_update())
return;
@@ -1149,7 +1149,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
shader->has_integrator_dependency = false;
/* generate surface shader */
if (shader->reference_count() && graph && output->input("Surface")->link) {
if (shader->used && graph && output->input("Surface")->link) {
shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
if (has_bump)
@@ -1165,7 +1165,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
}
/* generate volume shader */
if (shader->reference_count() && graph && output->input("Volume")->link) {
if (shader->used && graph && output->input("Volume")->link) {
shader->osl_volume_ref = compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
shader->has_volume = true;
}
@@ -1173,7 +1173,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
shader->osl_volume_ref = OSL::ShaderGroupRef();
/* generate displacement shader */
if (shader->reference_count() && graph && output->input("Displacement")->link) {
if (shader->used && graph && output->input("Displacement")->link) {
shader->osl_displacement_ref = compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
shader->has_displacement = true;
}

View File

@@ -72,18 +72,15 @@ class OSLShaderManager : public ShaderManager {
static void free_memory();
void reset(Scene *scene) override;
void reset(Scene *scene);
bool use_osl() override
bool use_osl()
{
return true;
}
void device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress) override;
void device_free(Device *device, DeviceScene *dscene, Scene *scene) override;
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene, Scene *scene);
/* osl compile and query */
static bool osl_compile(const string &inputfile, const string &outputfile);

View File

@@ -143,27 +143,21 @@ void Scene::free_memory(bool final)
delete bvh;
bvh = NULL;
/* The order of deletion is important to make sure data is freed based on possible dependencies
* as the Nodes' reference counts are decremented in the destructors:
*
* - Procedurals can create and hold pointers to any other types.
* - Objects can hold pointers to Geometries and ParticleSystems
* - Lights and Geometries can hold pointers to Shaders.
*
* Similarly, we first delete all nodes and their associated device data, and then the managers
* and their associated device data.
*/
foreach (Shader *s, shaders)
delete s;
/* delete procedurals before other types as they may hold pointers to those types */
foreach (Procedural *p, procedurals)
delete p;
foreach (Object *o, objects)
delete o;
foreach (Geometry *g, geometry)
delete g;
foreach (ParticleSystem *p, particle_systems)
delete p;
foreach (Object *o, objects)
delete o;
foreach (Light *l, lights)
delete l;
foreach (ParticleSystem *p, particle_systems)
delete p;
shaders.clear();
geometry.clear();
objects.clear();
lights.clear();
@@ -175,25 +169,7 @@ void Scene::free_memory(bool final)
film->device_free(device, &dscene, this);
background->device_free(device, &dscene);
integrator->device_free(device, &dscene, true);
}
if (final) {
delete camera;
delete dicing_camera;
delete film;
delete background;
delete integrator;
}
/* Delete Shaders after every other nodes to ensure that we do not try to decrement the reference
* count on some dangling pointer. */
foreach (Shader *s, shaders)
delete s;
shaders.clear();
/* Now that all nodes have been deleted, we can safely delete managers and device data. */
if (device) {
object_manager->device_free(device, &dscene, true);
geometry_manager->device_free(device, &dscene, true);
shader_manager->device_free(device, &dscene, this);
@@ -213,6 +189,11 @@ void Scene::free_memory(bool final)
if (final) {
delete lookup_tables;
delete camera;
delete dicing_camera;
delete film;
delete background;
delete integrator;
delete object_manager;
delete geometry_manager;
delete shader_manager;
@@ -523,6 +504,9 @@ bool Scene::update(Progress &progress, bool &kernel_switch_needed)
{
/* update scene */
if (need_update()) {
/* Updated used shader tag so we know which features are need for the kernel. */
shader_manager->update_shaders_used(this);
/* Update max_closures. */
KernelIntegrator *kintegrator = &dscene.data.integrator;
if (params.background) {
@@ -542,6 +526,9 @@ bool Scene::update(Progress &progress, bool &kernel_switch_needed)
DeviceKernelStatus kernel_switch_status = device->get_active_kernel_switch_state();
kernel_switch_needed = kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE ||
kernel_switch_status == DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
if (kernel_switch_status == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
progress.set_kernel_status("Compiling render kernels");
}
if (new_kernels_needed || kernel_switch_needed) {
progress.set_kernel_status("Compiling render kernels");
device->wait_for_availability(loaded_kernel_features);
@@ -579,6 +566,9 @@ bool Scene::load_kernels(Progress &progress, bool lock_scene)
return false;
}
progress.add_skip_time(timer, false);
VLOG(1) << "Total time spent loading kernels: " << time_dt() - timer.get_start();
kernels_loaded = true;
loaded_kernel_features = requested_features;
return true;
@@ -597,7 +587,7 @@ int Scene::get_max_closure_count()
int max_closures = 0;
for (int i = 0; i < shaders.size(); i++) {
Shader *shader = shaders[i];
if (shader->reference_count()) {
if (shader->used) {
int num_closures = shader->graph->get_num_closures();
max_closures = max(max_closures, num_closures);
}
@@ -758,10 +748,9 @@ template<> void Scene::delete_node_impl(ParticleSystem *node)
particle_system_manager->tag_update(this);
}
template<> void Scene::delete_node_impl(Shader *shader)
template<> void Scene::delete_node_impl(Shader * /*node*/)
{
/* don't delete unused shaders, not supported */
shader->clear_reference_count();
}
template<> void Scene::delete_node_impl(Procedural *node)
@@ -828,12 +817,9 @@ template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const No
particle_system_manager->tag_update(this);
}
template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner * /*owner*/)
template<> void Scene::delete_nodes(const set<Shader *> & /*nodes*/, const NodeOwner * /*owner*/)
{
/* don't delete unused shaders, not supported */
for (Shader *shader : nodes) {
shader->clear_reference_count();
}
}
template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner)

View File

@@ -243,6 +243,11 @@ void Session::run_gpu()
}
}
/* Don't go in pause mode when image was rendered with preview kernels
* When feature kernels become available the session will be reset. */
else if (no_tiles && kernel_state == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
time_sleep(0.1);
}
else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) {
reset_gpu(tile_manager.params, params.samples);
}
@@ -757,6 +762,11 @@ void Session::run_cpu()
}
}
/* Don't go in pause mode when preview kernels are used
* When feature kernels become available the session will be reset. */
else if (no_tiles && kernel_state == DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL) {
time_sleep(0.1);
}
else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) {
reset_cpu(tile_manager.params, params.samples);
}

View File

@@ -16,6 +16,7 @@
#include "device/device.h"
#include "render/alembic.h"
#include "render/background.h"
#include "render/camera.h"
#include "render/colorspace.h"
@@ -26,7 +27,6 @@
#include "render/nodes.h"
#include "render/object.h"
#include "render/osl.h"
#include "render/procedural.h"
#include "render/scene.h"
#include "render/shader.h"
#include "render/svm.h"
@@ -218,6 +218,7 @@ Shader::Shader() : Node(get_node_type())
displacement_method = DISPLACE_BUMP;
id = -1;
used = false;
need_update_uvs = true;
need_update_attribute = true;
@@ -381,9 +382,8 @@ void Shader::tag_used(Scene *scene)
{
/* if an unused shader suddenly gets used somewhere, it needs to be
* recompiled because it was skipped for compilation before */
if (!reference_count()) {
if (!used) {
tag_modified();
/* We do not reference here as the shader will be referenced when added to a socket. */
scene->shader_manager->tag_update(scene, ShaderManager::SHADER_MODIFIED);
}
}
@@ -461,28 +461,52 @@ int ShaderManager::get_shader_id(Shader *shader, bool smooth)
return id;
}
void ShaderManager::device_update(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
void ShaderManager::update_shaders_used(Scene *scene)
{
if (!need_update()) {
return;
}
/* figure out which shaders are in use, so SVM/OSL can skip compiling them
* for speed and avoid loading image textures into memory */
uint id = 0;
foreach (Shader *shader, scene->shaders) {
shader->used = false;
shader->id = id++;
}
/* Those shaders should always be compiled as they are used as fallback if a shader cannot be
* found, e.g. bad shader index for the triangle shaders on a Mesh. */
assert(scene->default_surface->reference_count() != 0);
assert(scene->default_light->reference_count() != 0);
assert(scene->default_background->reference_count() != 0);
assert(scene->default_empty->reference_count() != 0);
scene->default_surface->used = true;
scene->default_light->used = true;
scene->default_background->used = true;
scene->default_empty->used = true;
device_update_specific(device, dscene, scene, progress);
if (scene->background->get_shader())
scene->background->get_shader()->used = true;
#ifdef WITH_ALEMBIC
foreach (Procedural *procedural, scene->procedurals) {
AlembicProcedural *abc_proc = static_cast<AlembicProcedural *>(procedural);
foreach (Node *abc_node, abc_proc->get_objects()) {
AlembicObject *abc_object = static_cast<AlembicObject *>(abc_node);
foreach (Node *node, abc_object->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
shader->used = true;
}
}
}
#endif
foreach (Geometry *geom, scene->geometry)
foreach (Node *node, geom->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
shader->used = true;
}
foreach (Light *light, scene->lights)
if (light->get_shader())
const_cast<Shader *>(light->get_shader())->used = true;
}
void ShaderManager::device_update_common(Device *device,
@@ -615,7 +639,6 @@ void ShaderManager::add_default(Scene *scene)
Shader *shader = scene->create_node<Shader>();
shader->name = "default_surface";
shader->set_graph(graph);
shader->reference();
scene->default_surface = shader;
shader->tag_update(scene);
}
@@ -634,8 +657,6 @@ void ShaderManager::add_default(Scene *scene)
shader->set_graph(graph);
scene->default_volume = shader;
shader->tag_update(scene);
/* No default reference for the volume to avoid compiling volume kernels if there are no actual
* volumes in the scene */
}
/* default light */
@@ -652,7 +673,6 @@ void ShaderManager::add_default(Scene *scene)
Shader *shader = scene->create_node<Shader>();
shader->name = "default_light";
shader->set_graph(graph);
shader->reference();
scene->default_light = shader;
shader->tag_update(scene);
}
@@ -664,7 +684,6 @@ void ShaderManager::add_default(Scene *scene)
Shader *shader = scene->create_node<Shader>();
shader->name = "default_background";
shader->set_graph(graph);
shader->reference();
scene->default_background = shader;
shader->tag_update(scene);
}
@@ -676,7 +695,6 @@ void ShaderManager::add_default(Scene *scene)
Shader *shader = scene->create_node<Shader>();
shader->name = "default_empty";
shader->set_graph(graph);
shader->reference();
scene->default_empty = shader;
shader->tag_update(scene);
}
@@ -717,7 +735,7 @@ void ShaderManager::get_requested_features(Scene *scene,
requested_features->nodes_features = 0;
for (int i = 0; i < scene->shaders.size(); i++) {
Shader *shader = scene->shaders[i];
if (!shader->reference_count()) {
if (!shader->used) {
continue;
}

View File

@@ -132,6 +132,7 @@ class Shader : public Node {
/* determined before compiling */
uint id;
bool used;
#ifdef WITH_OSL
/* osl shading state references */
@@ -186,11 +187,10 @@ class ShaderManager {
}
/* device update */
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
virtual void device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress) = 0;
virtual void device_update(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress) = 0;
virtual void device_free(Device *device, DeviceScene *dscene, Scene *scene) = 0;
void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
@@ -208,6 +208,7 @@ class ShaderManager {
static void add_default(Scene *scene);
/* Selective nodes compilation. */
void update_shaders_used(Scene *scene);
void get_requested_features(Scene *scene, DeviceRequestedFeatures *requested_features);
static void free_memory();

View File

@@ -69,10 +69,10 @@ void SVMShaderManager::device_update_shader(Scene *scene,
<< summary.full_report();
}
void SVMShaderManager::device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
void SVMShaderManager::device_update(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
{
if (!need_update())
return;
@@ -776,7 +776,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
add_node(NODE_ENTER_BUMP_EVAL, bump_state_offset);
}
if (shader->reference_count()) {
if (shader->used) {
CompilerState state(graph);
if (clin->link) {
bool generate = false;

View File

@@ -44,13 +44,10 @@ class SVMShaderManager : public ShaderManager {
SVMShaderManager();
~SVMShaderManager();
void reset(Scene *scene) override;
void reset(Scene *scene);
void device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress) override;
void device_free(Device *device, DeviceScene *dscene, Scene *scene) override;
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene, Scene *scene);
protected:
void device_update_shader(Scene *scene,

View File

@@ -362,7 +362,7 @@ ccl_device float fast_atan2f(float y, float x)
ccl_device float fast_log2f(float x)
{
/* NOTE: clamp to avoid special cases and make result "safe" from large
* negative values/NAN's. */
* negative values/nans. */
x = clamp(x, FLT_MIN, FLT_MAX);
unsigned bits = __float_as_uint(x);
int exponent = (int)(bits >> 23) - 127;

View File

@@ -145,8 +145,7 @@ int system_cpu_num_active_group_processors()
return numaAPI_GetNumCurrentNodesProcessors();
}
/* Equivalent of Windows __cpuid for x86 processors on other platforms. */
#if (!defined(_WIN32) || defined(FREE_WINDOWS)) && (defined(__x86_64__) || defined(__i386__))
#if !defined(_WIN32) || defined(FREE_WINDOWS)
static void __cpuid(int data[4], int selector)
{
# if defined(__x86_64__)
@@ -167,34 +166,7 @@ static void __cpuid(int data[4], int selector)
string system_cpu_brand_string()
{
#if defined(__APPLE__)
/* Get from system on macOS. */
char modelname[512] = "";
size_t bufferlen = 512;
if (sysctlbyname("machdep.cpu.brand_string", &modelname, &bufferlen, NULL, 0) == 0) {
return modelname;
}
#elif defined(WIN32) || defined(__x86_64__) || defined(__i386__)
/* Get from intrinsics on Windows and x86. */
char buf[49] = {0};
int result[4] = {0};
__cpuid(result, 0x80000000);
if (result[0] != 0 && result[0] >= (int)0x80000004) {
__cpuid((int *)(buf + 0), 0x80000002);
__cpuid((int *)(buf + 16), 0x80000003);
__cpuid((int *)(buf + 32), 0x80000004);
string brand = buf;
/* Make it a bit more presentable. */
brand = string_remove_trademark(brand);
return brand;
}
#else
/* Get from /proc/cpuinfo on Unix systems. */
#if !defined(WIN32) && !defined(__x86_64__) && !defined(__i386__)
FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
if (cpuinfo != nullptr) {
char cpuinfo_buf[513] = "";
@@ -214,6 +186,24 @@ string system_cpu_brand_string()
}
}
}
#else
char buf[49] = {0};
int result[4] = {0};
__cpuid(result, 0x80000000);
if (result[0] != 0 && result[0] >= (int)0x80000004) {
__cpuid((int *)(buf + 0), 0x80000002);
__cpuid((int *)(buf + 16), 0x80000003);
__cpuid((int *)(buf + 32), 0x80000004);
string brand = buf;
/* make it a bit more presentable */
brand = string_remove_trademark(brand);
return brand;
}
#endif
return "Unknown CPU";
}
@@ -223,7 +213,7 @@ int system_cpu_bits()
return (sizeof(void *) * 8);
}
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
#if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(_M_IX86)
struct CPUCapabilities {
bool x64;

View File

@@ -43,8 +43,8 @@ class vector : public std::vector<value_type, allocator_type> {
/* Try as hard as possible to use zero memory. */
void free_memory()
{
vector<value_type, allocator_type> empty;
BaseClass::swap(empty);
BaseClass::resize(0);
BaseClass::shrink_to_fit();
}
/* Some external API might demand working with std::vector. */

View File

@@ -22,17 +22,10 @@
#include <libavformat/avformat.h>
/* Check if our ffmpeg is new enough, avoids user complaints.
* Minimum supported version is currently 3.2.0 which mean the following library versions:
* libavutil > 55.30
* libavcodec > 57.60
* libavformat > 57.50
*
* We only check for one of these as they are usually updated in tandem.
*/
#if (LIBAVFORMAT_VERSION_MAJOR < 57) || \
((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR <= 50))
# error "FFmpeg 3.2.0 or newer is needed, Upgrade your FFmpeg or disable it"
/* check our ffmpeg is new enough, avoids user complaints */
#if (LIBAVFORMAT_VERSION_MAJOR < 52) || \
((LIBAVFORMAT_VERSION_MAJOR == 52) && (LIBAVFORMAT_VERSION_MINOR <= 64))
# error "FFmpeg 0.7 or newer is needed, Upgrade your FFmpeg or disable it"
#endif
/* end sanity check */
@@ -43,6 +36,274 @@
# define FFMPEG_INLINE static inline
#endif
#include <libavcodec/avcodec.h>
#include <libavutil/mathematics.h>
#include <libavutil/opt.h>
#include <libavutil/rational.h>
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
# define FFMPEG_HAVE_PARSE_UTILS 1
# include <libavutil/parseutils.h>
#endif
#include <libswscale/swscale.h>
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 105))
# define FFMPEG_HAVE_AVIO 1
#endif
#if (LIBAVCODEC_VERSION_MAJOR > 53) || \
((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR > 1)) || \
((LIBAVCODEC_VERSION_MAJOR == 53) && (LIBAVCODEC_VERSION_MINOR == 1) && \
(LIBAVCODEC_VERSION_MICRO >= 1)) || \
((LIBAVCODEC_VERSION_MAJOR == 52) && (LIBAVCODEC_VERSION_MINOR >= 121))
# define FFMPEG_HAVE_DEFAULT_VAL_UNION 1
#endif
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 101))
# define FFMPEG_HAVE_AV_DUMP_FORMAT 1
#endif
#if (LIBAVFORMAT_VERSION_MAJOR > 52) || \
((LIBAVFORMAT_VERSION_MAJOR >= 52) && (LIBAVFORMAT_VERSION_MINOR >= 45))
# define FFMPEG_HAVE_AV_GUESS_FORMAT 1
#endif
#if (LIBAVCODEC_VERSION_MAJOR > 52) || \
((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 23))
# define FFMPEG_HAVE_DECODE_AUDIO3 1
# define FFMPEG_HAVE_DECODE_VIDEO2 1
#endif
#if (LIBAVCODEC_VERSION_MAJOR > 52) || \
((LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 64))
# define FFMPEG_HAVE_AVMEDIA_TYPES 1
#endif
#if ((LIBAVCODEC_VERSION_MAJOR > 52) || \
(LIBAVCODEC_VERSION_MAJOR >= 52) && (LIBAVCODEC_VERSION_MINOR >= 29)) && \
((LIBSWSCALE_VERSION_MAJOR > 0) || \
(LIBSWSCALE_VERSION_MAJOR >= 0) && (LIBSWSCALE_VERSION_MINOR >= 10))
# define FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
#endif
#if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
(LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR > 14))
# define FFMPEG_HAVE_CANON_H264_RESOLUTION_FIX
#endif
#if ((LIBAVCODEC_VERSION_MAJOR > 53) || \
(LIBAVCODEC_VERSION_MAJOR >= 53) && (LIBAVCODEC_VERSION_MINOR >= 60))
# define FFMPEG_HAVE_ENCODE_AUDIO2
#endif
#if ((LIBAVCODEC_VERSION_MAJOR > 53) || \
(LIBAVCODEC_VERSION_MAJOR >= 53) && (LIBAVCODEC_VERSION_MINOR >= 42))
# define FFMPEG_HAVE_DECODE_AUDIO4
#endif
#if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
(LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
# define FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
#endif
#if ((LIBAVUTIL_VERSION_MAJOR > 51) || \
(LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR >= 21))
# define FFMPEG_FFV1_ALPHA_SUPPORTED
# define FFMPEG_SAMPLE_FMT_S16P_SUPPORTED
#else
FFMPEG_INLINE
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
{
/* no planar formats in FFmpeg < 0.9 */
(void)sample_fmt;
return 0;
}
#endif
/* XXX TODO Probably fix to correct modern flags in code? Not sure how old FFMPEG we want to
* support though, so for now this will do. */
#ifndef FF_MIN_BUFFER_SIZE
# ifdef AV_INPUT_BUFFER_MIN_SIZE
# define FF_MIN_BUFFER_SIZE AV_INPUT_BUFFER_MIN_SIZE
# endif
#endif
#ifndef FF_INPUT_BUFFER_PADDING_SIZE
# ifdef AV_INPUT_BUFFER_PADDING_SIZE
# define FF_INPUT_BUFFER_PADDING_SIZE AV_INPUT_BUFFER_PADDING_SIZE
# endif
#endif
#ifndef CODEC_FLAG_GLOBAL_HEADER
# ifdef AV_CODEC_FLAG_GLOBAL_HEADER
# define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
# endif
#endif
#ifndef CODEC_FLAG_GLOBAL_HEADER
# ifdef AV_CODEC_FLAG_GLOBAL_HEADER
# define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
# endif
#endif
#ifndef CODEC_FLAG_INTERLACED_DCT
# ifdef AV_CODEC_FLAG_INTERLACED_DCT
# define CODEC_FLAG_INTERLACED_DCT AV_CODEC_FLAG_INTERLACED_DCT
# endif
#endif
#ifndef CODEC_FLAG_INTERLACED_ME
# ifdef AV_CODEC_FLAG_INTERLACED_ME
# define CODEC_FLAG_INTERLACED_ME AV_CODEC_FLAG_INTERLACED_ME
# endif
#endif
/* FFmpeg upstream 1.0 is the first who added AV_ prefix. */
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100)
# define AV_CODEC_ID_NONE CODEC_ID_NONE
# define AV_CODEC_ID_MPEG4 CODEC_ID_MPEG4
# define AV_CODEC_ID_MJPEG CODEC_ID_MJPEG
# define AV_CODEC_ID_DNXHD CODEC_ID_DNXHD
# define AV_CODEC_ID_MPEG2VIDEO CODEC_ID_MPEG2VIDEO
# define AV_CODEC_ID_MPEG1VIDEO CODEC_ID_MPEG1VIDEO
# define AV_CODEC_ID_DVVIDEO CODEC_ID_DVVIDEO
# define AV_CODEC_ID_THEORA CODEC_ID_THEORA
# define AV_CODEC_ID_PNG CODEC_ID_PNG
# define AV_CODEC_ID_QTRLE CODEC_ID_QTRLE
# define AV_CODEC_ID_FFV1 CODEC_ID_FFV1
# define AV_CODEC_ID_HUFFYUV CODEC_ID_HUFFYUV
# define AV_CODEC_ID_H264 CODEC_ID_H264
# define AV_CODEC_ID_FLV1 CODEC_ID_FLV1
# define AV_CODEC_ID_AAC CODEC_ID_AAC
# define AV_CODEC_ID_AC3 CODEC_ID_AC3
# define AV_CODEC_ID_MP3 CODEC_ID_MP3
# define AV_CODEC_ID_MP2 CODEC_ID_MP2
# define AV_CODEC_ID_FLAC CODEC_ID_FLAC
# define AV_CODEC_ID_PCM_U8 CODEC_ID_PCM_U8
# define AV_CODEC_ID_PCM_S16LE CODEC_ID_PCM_S16LE
# define AV_CODEC_ID_PCM_S24LE CODEC_ID_PCM_S24LE
# define AV_CODEC_ID_PCM_S32LE CODEC_ID_PCM_S32LE
# define AV_CODEC_ID_PCM_F32LE CODEC_ID_PCM_F32LE
# define AV_CODEC_ID_PCM_F64LE CODEC_ID_PCM_F64LE
# define AV_CODEC_ID_VORBIS CODEC_ID_VORBIS
#endif
FFMPEG_INLINE
int av_get_cropped_height_from_codec(AVCodecContext *pCodecCtx)
{
int y = pCodecCtx->height;
#ifndef FFMPEG_HAVE_CANON_H264_RESOLUTION_FIX
/* really bad hack to remove this dreadfull black bar at the bottom
with Canon footage and old ffmpeg versions.
(to fix this properly in older ffmpeg versions one has to write a new
demuxer...)
see the actual fix here for reference:
http://git.libav.org/?p=libav.git;a=commit;h=30f515091c323da59c0f1b533703dedca2f4b95d
We do our best to apply this only to matching footage.
*/
if (pCodecCtx->width == 1920 && pCodecCtx->height == 1088 &&
pCodecCtx->pix_fmt == PIX_FMT_YUVJ420P && pCodecCtx->codec_id == AV_CODEC_ID_H264) {
y = 1080;
}
#endif
return y;
}
#if ((LIBAVUTIL_VERSION_MAJOR < 51) || \
(LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 22))
FFMPEG_INLINE
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
{
const AVOption *rv = NULL;
(void)search_flags;
av_set_string3(obj, name, val, 1, &rv);
return rv != NULL;
}
FFMPEG_INLINE
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
{
const AVOption *rv = NULL;
(void)search_flags;
rv = av_set_int(obj, name, val);
return rv != NULL;
}
FFMPEG_INLINE
int av_opt_set_double(void *obj, const char *name, double val, int search_flags)
{
const AVOption *rv = NULL;
(void)search_flags;
rv = av_set_double(obj, name, val);
return rv != NULL;
}
# define AV_OPT_TYPE_INT FF_OPT_TYPE_INT
# define AV_OPT_TYPE_INT64 FF_OPT_TYPE_INT64
# define AV_OPT_TYPE_STRING FF_OPT_TYPE_STRING
# define AV_OPT_TYPE_CONST FF_OPT_TYPE_CONST
# define AV_OPT_TYPE_DOUBLE FF_OPT_TYPE_DOUBLE
# define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT
#endif
#if ((LIBAVUTIL_VERSION_MAJOR < 51) || \
(LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 54))
FFMPEG_INLINE
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
{
if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
return AV_SAMPLE_FMT_NONE;
return sample_fmt;
}
#endif
#if ((LIBAVCODEC_VERSION_MAJOR < 53) || \
(LIBAVCODEC_VERSION_MAJOR == 53 && LIBAVCODEC_VERSION_MINOR < 35))
FFMPEG_INLINE
int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
{
/* TODO: no options are taking into account */
(void)options;
return avcodec_open(avctx, codec);
}
#endif
#if ((LIBAVFORMAT_VERSION_MAJOR < 53) || \
(LIBAVFORMAT_VERSION_MAJOR == 53 && LIBAVFORMAT_VERSION_MINOR < 21))
FFMPEG_INLINE
AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
{
/* TODO: no codec is taking into account */
(void)c;
return av_new_stream(s, 0);
}
FFMPEG_INLINE
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
{
/* TODO: no options are taking into account */
(void)options;
return av_find_stream_info(ic);
}
#endif
#if ((LIBAVFORMAT_VERSION_MAJOR > 53) || \
((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR > 32)) || \
((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR == 24) && \
(LIBAVFORMAT_VERSION_MICRO >= 100)))
FFMPEG_INLINE
void my_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
{
@@ -62,12 +323,103 @@ void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
{
my_update_cur_dts(s, ref_st, timestamp);
}
#endif
#if ((LIBAVCODEC_VERSION_MAJOR < 54) || \
(LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR < 28))
FFMPEG_INLINE
void avcodec_free_frame(AVFrame **frame)
{
/* don't need to do anything with old AVFrame
* since it does not have malloced members */
(void)frame;
}
#endif
#if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
(LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
# define FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
#endif
#if ((LIBAVCODEC_VERSION_MAJOR > 54) || \
(LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR >= 13))
# define FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
#endif
#ifndef FFMPEG_HAVE_AVIO
# define AVIO_FLAG_WRITE URL_WRONLY
# define avio_open url_fopen
# define avio_tell url_ftell
# define avio_close url_fclose
# define avio_size url_fsize
#endif
/* There are some version in between, which have avio_... functions but no
* AVIO_FLAG_... */
#ifndef AVIO_FLAG_WRITE
# define AVIO_FLAG_WRITE URL_WRONLY
#endif
#ifndef AV_PKT_FLAG_KEY
# define AV_PKT_FLAG_KEY PKT_FLAG_KEY
#endif
#ifndef FFMPEG_HAVE_AV_DUMP_FORMAT
# define av_dump_format dump_format
#endif
#ifndef FFMPEG_HAVE_AV_GUESS_FORMAT
# define av_guess_format guess_format
#endif
#ifndef FFMPEG_HAVE_PARSE_UTILS
# define av_parse_video_rate av_parse_video_frame_rate
#endif
#ifdef FFMPEG_HAVE_DEFAULT_VAL_UNION
# define FFMPEG_DEF_OPT_VAL_INT(OPT) OPT->default_val.i64
# define FFMPEG_DEF_OPT_VAL_DOUBLE(OPT) OPT->default_val.dbl
#else
# define FFMPEG_DEF_OPT_VAL_INT(OPT) OPT->default_val
# define FFMPEG_DEF_OPT_VAL_DOUBLE(OPT) OPT->default_val
#endif
#ifndef FFMPEG_HAVE_AVMEDIA_TYPES
# define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
# define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
#endif
#ifndef FFMPEG_HAVE_DECODE_AUDIO3
FFMPEG_INLINE
int avcodec_decode_audio3(AVCodecContext *avctx,
int16_t *samples,
int *frame_size_ptr,
AVPacket *avpkt)
{
return avcodec_decode_audio2(avctx, samples, frame_size_ptr, avpkt->data, avpkt->size);
}
#endif
#ifndef FFMPEG_HAVE_DECODE_VIDEO2
FFMPEG_INLINE
int avcodec_decode_video2(AVCodecContext *avctx,
AVFrame *picture,
int *got_picture_ptr,
AVPacket *avpkt)
{
return avcodec_decode_video(avctx, picture, got_picture_ptr, avpkt->data, avpkt->size);
}
#endif
FFMPEG_INLINE
int64_t av_get_pts_from_frame(AVFormatContext *avctx, AVFrame *picture)
{
int64_t pts;
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 34, 100)
pts = picture->pts;
#else
pts = picture->pkt_pts;
#endif
if (pts == AV_NOPTS_VALUE) {
pts = picture->pkt_dts;
@@ -80,16 +432,124 @@ int64_t av_get_pts_from_frame(AVFormatContext *avctx, AVFrame *picture)
return pts;
}
/* -------------------------------------------------------------------- */
/** \name Deinterlace code block
*
* NOTE: The code in this block are from FFmpeg 2.6.4, which is licensed by LGPL.
* \{ */
/* obsolete constant formerly defined in FFMpeg libavcodec/avcodec.h */
#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
# define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
#endif
#define MAX_NEG_CROP 1024
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 1, 0)
FFMPEG_INLINE
int avcodec_encode_video2(AVCodecContext *avctx,
AVPacket *pkt,
const AVFrame *frame,
int *got_output)
{
int outsize, ret;
#define times4(x) x, x, x, x
#define times256(x) times4(times4(times4(times4(times4(x)))))
ret = av_new_packet(pkt, avctx->width * avctx->height * 7 + 10000);
if (ret < 0)
return ret;
outsize = avcodec_encode_video(avctx, pkt->data, pkt->size, frame);
if (outsize <= 0) {
*got_output = 0;
av_free_packet(pkt);
}
else {
*got_output = 1;
av_shrink_packet(pkt, outsize);
if (avctx->coded_frame) {
pkt->pts = avctx->coded_frame->pts;
if (avctx->coded_frame->key_frame)
pkt->flags |= AV_PKT_FLAG_KEY;
}
}
return outsize >= 0 ? 0 : outsize;
}
#endif
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 17, 0)
FFMPEG_INLINE
void avformat_close_input(AVFormatContext **ctx)
{
av_close_input_file(*ctx);
*ctx = NULL;
}
#endif
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 8, 0)
FFMPEG_INLINE
AVFrame *av_frame_alloc(void)
{
return avcodec_alloc_frame();
}
FFMPEG_INLINE
void av_frame_free(AVFrame **frame)
{
av_freep(frame);
}
#endif
FFMPEG_INLINE
const char *av_get_metadata_key_value(AVDictionary *metadata, const char *key)
{
if (metadata == NULL) {
return NULL;
}
AVDictionaryEntry *tag = NULL;
while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
if (!strcmp(tag->key, key)) {
return tag->value;
}
}
return NULL;
}
FFMPEG_INLINE
bool av_check_encoded_with_ffmpeg(AVFormatContext *ctx)
{
const char *encoder = av_get_metadata_key_value(ctx->metadata, "ENCODER");
if (encoder != NULL && !strncmp(encoder, "Lavf", 4)) {
return true;
}
return false;
}
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 32, 0)
# define AV_OPT_SEARCH_FAKE_OBJ 0
#endif
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100)
# define FFMPEG_HAVE_DEPRECATED_FLAGS2
#endif
/* Since FFmpeg-1.1 this constant have AV_ prefix. */
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 3, 100)
# define AV_PIX_FMT_BGR32 PIX_FMT_BGR32
# define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
# define AV_PIX_FMT_BGRA PIX_FMT_BGRA
# define AV_PIX_FMT_ARGB PIX_FMT_ARGB
# define AV_PIX_FMT_RGBA PIX_FMT_RGBA
#endif
/* New API from FFmpeg-2.0 which soon became recommended one. */
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 38, 100)
# define av_frame_alloc avcodec_alloc_frame
# define av_frame_free avcodec_free_frame
# define av_frame_unref avcodec_get_frame_defaults
#endif
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 24, 102)
/* NOTE: The code in this block are from FFmpeg 2.6.4, which is licensed by LGPL. */
# define MAX_NEG_CROP 1024
# define times4(x) x, x, x, x
# define times256(x) times4(times4(times4(times4(times4(x)))))
static const uint8_t ff_compat_crop_tab[256 + 2 * MAX_NEG_CROP] = {
times256(0x00), 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
@@ -115,8 +575,8 @@ static const uint8_t ff_compat_crop_tab[256 + 2 * MAX_NEG_CROP] = {
0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
0xFB, 0xFC, 0xFD, 0xFE, 0xFF, times256(0xFF)};
#undef times4
#undef times256
# undef times4
# undef times256
/* filter parameters: [-1 4 2 4 -1] // 8 */
FFMPEG_INLINE
@@ -208,9 +668,8 @@ int deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, int width, int
uint8_t *src_m1, *src_0, *src_p1, *src_p2;
int y;
uint8_t *buf = (uint8_t *)av_malloc(width);
if (!buf) {
if (!buf)
return AVERROR(ENOMEM);
}
src_m1 = src1;
memcpy(buf, src_m1, width);
@@ -230,21 +689,24 @@ int deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, int width, int
return 0;
}
# ifdef __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
# endif
FFMPEG_INLINE
int av_image_deinterlace(
AVFrame *dst, const AVFrame *src, enum AVPixelFormat pix_fmt, int width, int height)
int avpicture_deinterlace(
AVPicture *dst, const AVPicture *src, enum AVPixelFormat pix_fmt, int width, int height)
{
int i, ret;
if (pix_fmt != AV_PIX_FMT_YUV420P && pix_fmt != AV_PIX_FMT_YUVJ420P &&
pix_fmt != AV_PIX_FMT_YUV422P && pix_fmt != AV_PIX_FMT_YUVJ422P &&
pix_fmt != AV_PIX_FMT_YUV444P && pix_fmt != AV_PIX_FMT_YUV411P &&
pix_fmt != AV_PIX_FMT_GRAY8) {
pix_fmt != AV_PIX_FMT_GRAY8)
return -1;
}
if ((width & 3) != 0 || (height & 3) != 0) {
if ((width & 3) != 0 || (height & 3) != 0)
return -1;
}
for (i = 0; i < 3; i++) {
if (i == 1) {
@@ -270,9 +732,8 @@ int av_image_deinterlace(
}
if (src == dst) {
ret = deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], width, height);
if (ret < 0) {
if (ret < 0)
return ret;
}
}
else {
deinterlace_bottom_field(
@@ -282,6 +743,10 @@ int av_image_deinterlace(
return 0;
}
/** \} Deinterlace code block */
# ifdef __GNUC__
# pragma GCC diagnostic pop
# endif
#endif
#endif

View File

@@ -79,7 +79,6 @@ set(SRC
intern/GHOST_SystemPaths.h
intern/GHOST_TimerManager.h
intern/GHOST_TimerTask.h
intern/GHOST_Util.h
intern/GHOST_Window.h
intern/GHOST_WindowManager.h
)
@@ -439,7 +438,6 @@ endif()
if(WITH_XR_OPENXR)
list(APPEND SRC
intern/GHOST_Xr.cpp
intern/GHOST_XrAction.cpp
intern/GHOST_XrContext.cpp
intern/GHOST_XrEvent.cpp
intern/GHOST_XrGraphicsBinding.cpp
@@ -448,7 +446,6 @@ if(WITH_XR_OPENXR)
GHOST_IXrContext.h
intern/GHOST_IXrGraphicsBinding.h
intern/GHOST_XrAction.h
intern/GHOST_XrContext.h
intern/GHOST_XrException.h
intern/GHOST_XrSession.h

View File

@@ -276,7 +276,7 @@ extern int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle);
* wait (block) until the next event before returning.
* \return Indication of the presence of events.
*/
extern bool GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, bool waitForEvent);
extern int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent);
/**
* Retrieves events from the queue and send them to the event consumers.
@@ -1059,110 +1059,7 @@ int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_XrContextHandle xr_context
* \returns GHOST_kSuccess if any event was handled, otherwise GHOST_kFailure.
*/
GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContextHandle xr_context);
/* actions */
/**
* Create an OpenXR action set for input/output.
*/
int GHOST_XrCreateActionSet(GHOST_XrContextHandle xr_context, const GHOST_XrActionSetInfo *info);
/**
* Destroy a previously created OpenXR action set.
*/
void GHOST_XrDestroyActionSet(GHOST_XrContextHandle xr_context, const char *action_set_name);
/**
* Create OpenXR input/output actions.
*/
int GHOST_XrCreateActions(GHOST_XrContextHandle xr_context,
const char *action_set_name,
GHOST_TUns32 count,
const GHOST_XrActionInfo *infos);
/**
* Destroy previously created OpenXR actions.
*/
void GHOST_XrDestroyActions(GHOST_XrContextHandle xr_context,
const char *action_set_name,
GHOST_TUns32 count,
const char *const *action_names);
/**
* Create spaces for pose-based OpenXR actions.
*/
int GHOST_XrCreateActionSpaces(GHOST_XrContextHandle xr_context,
const char *action_set_name,
GHOST_TUns32 count,
const GHOST_XrActionSpaceInfo *infos);
/**
* Destroy previously created spaces for OpenXR actions.
*/
void GHOST_XrDestroyActionSpaces(GHOST_XrContextHandle xr_context,
const char *action_set_name,
GHOST_TUns32 count,
const GHOST_XrActionSpaceInfo *infos);
/**
* Create input/output path bindings for OpenXR actions.
*/
int GHOST_XrCreateActionBindings(GHOST_XrContextHandle xr_context,
const char *action_set_name,
GHOST_TUns32 count,
const GHOST_XrActionProfileInfo *infos);
/**
* Destroy previously created bindings for OpenXR actions.
*/
void GHOST_XrDestroyActionBindings(GHOST_XrContextHandle xr_context,
const char *action_set_name,
GHOST_TUns32 count,
const GHOST_XrActionProfileInfo *infos);
/**
* Attach all created action sets to the current OpenXR session.
*/
int GHOST_XrAttachActionSets(GHOST_XrContextHandle xr_context);
/**
* Update button/tracking states for OpenXR actions.
*
* \param action_set_name: The name of the action set to sync. If NULL, all action sets
* attached to the session will be synced.
*/
int GHOST_XrSyncActions(GHOST_XrContextHandle xr_context, const char *action_set_name);
/**
* Apply an OpenXR haptic output action.
*/
int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name,
const GHOST_TInt64 *duration,
const float *frequency,
const float *amplitude);
/**
* Stop a previously applied OpenXR haptic output action.
*/
void GHOST_XrStopHapticAction(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name);
/**
* Get action set custom data (owned by Blender, not GHOST).
*/
void *GHOST_XrGetActionSetCustomdata(GHOST_XrContextHandle xr_context,
const char *action_set_name);
/**
* Get action custom data (owned by Blender, not GHOST).
*/
void *GHOST_XrGetActionCustomdata(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name);
#endif /* WITH_XR_OPENXR */
#endif
#ifdef __cplusplus
}

View File

@@ -22,8 +22,6 @@
#include "GHOST_Types.h"
class GHOST_XrSession;
class GHOST_IXrContext {
public:
virtual ~GHOST_IXrContext() = default;
@@ -33,10 +31,6 @@ class GHOST_IXrContext {
virtual bool isSessionRunning() const = 0;
virtual void drawSessionViews(void *draw_customdata) = 0;
/* Needed for the GHOST C api. */
virtual GHOST_XrSession *getSession() = 0;
virtual const GHOST_XrSession *getSession() const = 0;
virtual void dispatchErrorMessage(const class GHOST_XrException *) const = 0;
virtual void setGraphicsContextBindFuncs(GHOST_XrGraphicsContextBindFn bind_fn,

Some files were not shown because too many files have changed in this diff Show More