Compare commits
49 Commits
refactor-i
...
tmp-T80603
Author | SHA1 | Date | |
---|---|---|---|
960a005bab | |||
141eb92345 | |||
8289fc688b | |||
f575a14801 | |||
![]() |
91f07fbfd6 | ||
6e13cff487 | |||
68fae13d9b | |||
![]() |
e553408bee | ||
17ddb4c4ea | |||
dceaef92d7 | |||
465d5c018e | |||
3bbcc4f6e8 | |||
58533aca4d | |||
5f01048dcb | |||
945e18f037 | |||
293b00beb5 | |||
517f32045c | |||
4f3fdf7715 | |||
![]() |
554ed613ae | ||
783d3c675a | |||
![]() |
e21a903b98 | ||
0148059c68 | |||
d114288f90 | |||
3947cbf916 | |||
![]() |
37a07d8a75 | ||
8e555bf4e3 | |||
0178e7b393 | |||
42a517779a | |||
60bf482dba | |||
ce11640eef | |||
c26cd6e996 | |||
0a8eeae831 | |||
f649e5c418 | |||
5439f43e88 | |||
5fc252feae | |||
296e3ee62c | |||
c310bf4ebe | |||
548312ed82 | |||
56b345adc6 | |||
404c3adfcc | |||
9d5e5e282c | |||
7b754c8c99 | |||
1510c04d41 | |||
2c3ef36a0b | |||
0402cc7e9e | |||
09db0f2a34 | |||
e4ac4769f1 | |||
864f8cbb86 | |||
488bf53207 |
@@ -8,7 +8,7 @@ Code signing is done as part of INSTALL target, which makes it possible to sign
|
||||
files which are aimed into a bundle and coming from a non-signed source (such as
|
||||
libraries SVN).
|
||||
|
||||
This is achieved by specifying `slave_codesign.cmake` as a post-install script
|
||||
This is achieved by specifying `worker_codesign.cmake` as a post-install script
|
||||
run by CMake. This CMake script simply involves an utility script written in
|
||||
Python which takes care of an actual signing.
|
||||
|
||||
|
@@ -40,8 +40,8 @@ class Builder:
|
||||
|
||||
# Buildbot runs from build/ directory
|
||||
self.blender_dir = os.path.abspath(os.path.join('..', 'blender.git'))
|
||||
self.build_dir = os.path.abspath(os.path.join('..', 'build', name))
|
||||
self.install_dir = os.path.abspath(os.path.join('..', 'install', name))
|
||||
self.build_dir = os.path.abspath(os.path.join('..', 'build'))
|
||||
self.install_dir = os.path.abspath(os.path.join('..', 'install'))
|
||||
self.upload_dir = os.path.abspath(os.path.join('..', 'install'))
|
||||
|
||||
# Detect platform
|
||||
|
@@ -48,6 +48,7 @@ import shutil
|
||||
import subprocess
|
||||
import time
|
||||
import tarfile
|
||||
import uuid
|
||||
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
@@ -121,21 +122,10 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
# Consider this an input of the code signing server.
|
||||
unsigned_storage_dir: Path
|
||||
|
||||
# Information about archive which contains files which are to be signed.
|
||||
#
|
||||
# This archive is created by the buildbot worked and acts as an input for
|
||||
# the code signing server.
|
||||
unsigned_archive_info: ArchiveWithIndicator
|
||||
|
||||
# Storage where signed files are stored.
|
||||
# Consider this an output of the code signer server.
|
||||
signed_storage_dir: Path
|
||||
|
||||
# Information about archive which contains signed files.
|
||||
#
|
||||
# This archive is created by the code signing server.
|
||||
signed_archive_info: ArchiveWithIndicator
|
||||
|
||||
# Platform the code is currently executing on.
|
||||
platform: util.Platform
|
||||
|
||||
@@ -146,50 +136,44 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
|
||||
# Unsigned (signing server input) configuration.
|
||||
self.unsigned_storage_dir = absolute_shared_storage_dir / 'unsigned'
|
||||
self.unsigned_archive_info = ArchiveWithIndicator(
|
||||
self.unsigned_storage_dir, 'unsigned_files.tar', 'ready.stamp')
|
||||
|
||||
# Signed (signing server output) configuration.
|
||||
self.signed_storage_dir = absolute_shared_storage_dir / 'signed'
|
||||
self.signed_archive_info = ArchiveWithIndicator(
|
||||
self.signed_storage_dir, 'signed_files.tar', 'ready.stamp')
|
||||
|
||||
self.platform = util.get_current_platform()
|
||||
|
||||
"""
|
||||
General note on cleanup environment functions.
|
||||
|
||||
It is expected that there is only one instance of the code signer server
|
||||
running for a given input/output directory, and that it serves a single
|
||||
buildbot worker.
|
||||
By its nature, a buildbot worker only produces one build at a time and
|
||||
never performs concurrent builds.
|
||||
This leads to a conclusion that when starting in a clean environment
|
||||
there shouldn't be any archives remaining from a previous build.
|
||||
|
||||
However, it is possible to have various failure scenarios which might
|
||||
leave the environment in a non-clean state:
|
||||
|
||||
- Network hiccup which makes buildbot worker to stop current build
|
||||
and re-start it after connection to server is re-established.
|
||||
|
||||
Note, this could also happen during buildbot server maintenance.
|
||||
|
||||
- Signing server might get restarted due to updates or other reasons.
|
||||
|
||||
Requiring manual interaction in such cases is not something good to
|
||||
require, so here we simply assume that the system is used the way it is
|
||||
intended to and restore environment to a prestine clean state.
|
||||
"""
|
||||
|
||||
def cleanup_environment_for_builder(self) -> None:
|
||||
self.unsigned_archive_info.clean()
|
||||
self.signed_archive_info.clean()
|
||||
# TODO(sergey): Revisit need of cleaning up the existing files.
|
||||
# In practice it wasn't so helpful, and with multiple clients
|
||||
# talking to the same server it becomes even mor etricky.
|
||||
pass
|
||||
|
||||
def cleanup_environment_for_signing_server(self) -> None:
|
||||
# Don't clear the requested to-be-signed archive since we might be
|
||||
# restarting signing machine while the buildbot is busy.
|
||||
self.signed_archive_info.clean()
|
||||
# TODO(sergey): Revisit need of cleaning up the existing files.
|
||||
# In practice it wasn't so helpful, and with multiple clients
|
||||
# talking to the same server it becomes even mor etricky.
|
||||
pass
|
||||
|
||||
def generate_request_id(self) -> str:
|
||||
"""
|
||||
Generate an unique identifier for code signing request.
|
||||
"""
|
||||
return str(uuid.uuid4())
|
||||
|
||||
def archive_info_for_request_id(
|
||||
self, path: Path, request_id: str) -> ArchiveWithIndicator:
|
||||
return ArchiveWithIndicator(
|
||||
path, f'{request_id}.tar', f'{request_id}.ready')
|
||||
|
||||
def signed_archive_info_for_request_id(
|
||||
self, request_id: str) -> ArchiveWithIndicator:
|
||||
return self.archive_info_for_request_id(
|
||||
self.signed_storage_dir, request_id);
|
||||
|
||||
def unsigned_archive_info_for_request_id(
|
||||
self, request_id: str) -> ArchiveWithIndicator:
|
||||
return self.archive_info_for_request_id(
|
||||
self.unsigned_storage_dir, request_id);
|
||||
|
||||
############################################################################
|
||||
# Buildbot worker side helpers.
|
||||
@@ -232,7 +216,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
if self.check_file_is_to_be_signed(file)]
|
||||
return files_to_be_signed
|
||||
|
||||
def wait_for_signed_archive_or_die(self) -> None:
|
||||
def wait_for_signed_archive_or_die(self, request_id) -> None:
|
||||
"""
|
||||
Wait until archive with signed files is available.
|
||||
|
||||
@@ -240,13 +224,19 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
is still no responce from the signing server the application will exit
|
||||
with a non-zero exit code.
|
||||
"""
|
||||
|
||||
signed_archive_info = self.signed_archive_info_for_request_id(
|
||||
request_id)
|
||||
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
|
||||
request_id)
|
||||
|
||||
timeout_in_seconds = self.config.TIMEOUT_IN_SECONDS
|
||||
time_start = time.monotonic()
|
||||
while not self.signed_archive_info.is_ready():
|
||||
while not signed_archive_info.is_ready():
|
||||
time.sleep(1)
|
||||
time_slept_in_seconds = time.monotonic() - time_start
|
||||
if time_slept_in_seconds > timeout_in_seconds:
|
||||
self.unsigned_archive_info.clean()
|
||||
unsigned_archive_info.clean()
|
||||
raise SystemExit("Signing server didn't finish signing in "
|
||||
f"{timeout_in_seconds} seconds, dying :(")
|
||||
|
||||
@@ -303,13 +293,19 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
return
|
||||
logger_builder.info('Found %d files to sign.', len(files))
|
||||
|
||||
request_id = self.generate_request_id()
|
||||
signed_archive_info = self.signed_archive_info_for_request_id(
|
||||
request_id)
|
||||
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
|
||||
request_id)
|
||||
|
||||
pack_files(files=files,
|
||||
archive_filepath=self.unsigned_archive_info.archive_filepath)
|
||||
self.unsigned_archive_info.tag_ready()
|
||||
archive_filepath=unsigned_archive_info.archive_filepath)
|
||||
unsigned_archive_info.tag_ready()
|
||||
|
||||
# Wait for the signing server to finish signing.
|
||||
logger_builder.info('Waiting signing server to sign the files...')
|
||||
self.wait_for_signed_archive_or_die()
|
||||
self.wait_for_signed_archive_or_die(request_id)
|
||||
|
||||
# Extract signed files from archive and move files to final location.
|
||||
with TemporaryDirectory(prefix='blender-buildbot-') as temp_dir_str:
|
||||
@@ -317,7 +313,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
|
||||
logger_builder.info('Extracting signed files from archive...')
|
||||
extract_files(
|
||||
archive_filepath=self.signed_archive_info.archive_filepath,
|
||||
archive_filepath=signed_archive_info.archive_filepath,
|
||||
extraction_dir=unpacked_signed_files_dir)
|
||||
|
||||
destination_dir = path
|
||||
@@ -327,19 +323,39 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
unpacked_signed_files_dir, destination_dir)
|
||||
|
||||
logger_builder.info('Removing archive with signed files...')
|
||||
self.signed_archive_info.clean()
|
||||
signed_archive_info.clean()
|
||||
|
||||
############################################################################
|
||||
# Signing server side helpers.
|
||||
|
||||
def wait_for_sign_request(self) -> None:
|
||||
def wait_for_sign_request(self) -> str:
|
||||
"""
|
||||
Wait for the buildbot to request signing of an archive.
|
||||
|
||||
Returns an identifier of signing request.
|
||||
"""
|
||||
|
||||
# TOOD(sergey): Support graceful shutdown on Ctrl-C.
|
||||
while not self.unsigned_archive_info.is_ready():
|
||||
|
||||
logger_server.info(
|
||||
'Waiting for a READY indicator of any signign request.')
|
||||
request_id = None
|
||||
while request_id is None:
|
||||
for file in self.unsigned_storage_dir.iterdir():
|
||||
if file.suffix != '.ready':
|
||||
continue
|
||||
request_id = file.stem
|
||||
logger_server.info(f'Found READY for request ID {request_id}.')
|
||||
if request_id is None:
|
||||
time.sleep(1)
|
||||
|
||||
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
|
||||
request_id)
|
||||
while not unsigned_archive_info.is_ready():
|
||||
time.sleep(1)
|
||||
|
||||
return request_id
|
||||
|
||||
@abc.abstractmethod
|
||||
def sign_all_files(self, files: List[AbsoluteAndRelativeFileName]) -> None:
|
||||
"""
|
||||
@@ -348,7 +364,7 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
NOTE: Signing should happen in-place.
|
||||
"""
|
||||
|
||||
def run_signing_pipeline(self):
|
||||
def run_signing_pipeline(self, request_id: str):
|
||||
"""
|
||||
Run the full signing pipeline starting from the point when buildbot
|
||||
worker have requested signing.
|
||||
@@ -360,9 +376,14 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
with TemporaryDirectory(prefix='blender-codesign-') as temp_dir_str:
|
||||
temp_dir = Path(temp_dir_str)
|
||||
|
||||
signed_archive_info = self.signed_archive_info_for_request_id(
|
||||
request_id)
|
||||
unsigned_archive_info = self.unsigned_archive_info_for_request_id(
|
||||
request_id)
|
||||
|
||||
logger_server.info('Extracting unsigned files from archive...')
|
||||
extract_files(
|
||||
archive_filepath=self.unsigned_archive_info.archive_filepath,
|
||||
archive_filepath=unsigned_archive_info.archive_filepath,
|
||||
extraction_dir=temp_dir)
|
||||
|
||||
logger_server.info('Collecting all files which needs signing...')
|
||||
@@ -374,11 +395,11 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
|
||||
logger_server.info('Packing signed files...')
|
||||
pack_files(files=files,
|
||||
archive_filepath=self.signed_archive_info.archive_filepath)
|
||||
self.signed_archive_info.tag_ready()
|
||||
archive_filepath=signed_archive_info.archive_filepath)
|
||||
signed_archive_info.tag_ready()
|
||||
|
||||
logger_server.info('Removing signing request...')
|
||||
self.unsigned_archive_info.clean()
|
||||
unsigned_archive_info.clean()
|
||||
|
||||
logger_server.info('Signing is complete.')
|
||||
|
||||
@@ -389,11 +410,11 @@ class BaseCodeSigner(metaclass=abc.ABCMeta):
|
||||
while True:
|
||||
logger_server.info('Waiting for the signing request in %s...',
|
||||
self.unsigned_storage_dir)
|
||||
self.wait_for_sign_request()
|
||||
request_id = self.wait_for_sign_request()
|
||||
|
||||
logger_server.info(
|
||||
'Got signing request, beging signign procedure.')
|
||||
self.run_signing_pipeline()
|
||||
f'Beging signign procedure for request ID {request_id}.')
|
||||
self.run_signing_pipeline(request_id)
|
||||
|
||||
############################################################################
|
||||
# Command executing.
|
||||
|
@@ -1,37 +0,0 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# Runs on buildbot slave, rsync zip directly to buildbot server rather
|
||||
# than using upload which is much slower
|
||||
|
||||
import buildbot_utils
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
builder = buildbot_utils.create_builder_from_arguments()
|
||||
|
||||
# rsync, this assumes ssh keys are setup so no password is needed
|
||||
local_zip = "buildbot_upload.zip"
|
||||
remote_folder = "builder.blender.org:/data/buildbot-master/uploaded/"
|
||||
remote_zip = remote_folder + "buildbot_upload_" + builder.name + ".zip"
|
||||
|
||||
command = ["rsync", "-avz", local_zip, remote_zip]
|
||||
buildbot_utils.call(command)
|
@@ -30,7 +30,7 @@ from tempfile import TemporaryDirectory, NamedTemporaryFile
|
||||
from typing import List
|
||||
|
||||
BUILDBOT_DIRECTORY = Path(__file__).absolute().parent
|
||||
CODESIGN_SCRIPT = BUILDBOT_DIRECTORY / 'slave_codesign.py'
|
||||
CODESIGN_SCRIPT = BUILDBOT_DIRECTORY / 'worker_codesign.py'
|
||||
BLENDER_GIT_ROOT_DIRECTORY = BUILDBOT_DIRECTORY.parent.parent
|
||||
DARWIN_DIRECTORY = BLENDER_GIT_ROOT_DIRECTORY / 'release' / 'darwin'
|
||||
|
@@ -33,7 +33,7 @@ else()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/slave_codesign.py"
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_LIST_DIR}/worker_codesign.py"
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
RESULT_VARIABLE exit_code
|
@@ -25,7 +25,7 @@ import buildbot_utils
|
||||
|
||||
def get_cmake_options(builder):
|
||||
post_install_script = os.path.join(
|
||||
builder.blender_dir, 'build_files', 'buildbot', 'slave_codesign.cmake')
|
||||
builder.blender_dir, 'build_files', 'buildbot', 'worker_codesign.cmake')
|
||||
|
||||
config_file = "build_files/cmake/config/blender_release.cmake"
|
||||
options = ['-DCMAKE_BUILD_TYPE:STRING=Release',
|
@@ -18,7 +18,7 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# Runs on buildbot slave, creating a release package using the build
|
||||
# Runs on buildbot worker, creating a release package using the build
|
||||
# system and zipping it into buildbot_upload.zip. This is then uploaded
|
||||
# to the master in the next buildbot step.
|
||||
|
||||
@@ -110,7 +110,7 @@ def pack_mac(builder):
|
||||
|
||||
release_dir = os.path.join(builder.blender_dir, 'release', 'darwin')
|
||||
buildbot_dir = os.path.join(builder.blender_dir, 'build_files', 'buildbot')
|
||||
bundle_script = os.path.join(buildbot_dir, 'slave_bundle_dmg.py')
|
||||
bundle_script = os.path.join(buildbot_dir, 'worker_bundle_dmg.py')
|
||||
|
||||
command = [bundle_script]
|
||||
command += ['--dmg', package_filepath]
|
42
extern/audaspace/plugins/sdl/SDLDevice.cpp
vendored
42
extern/audaspace/plugins/sdl/SDLDevice.cpp
vendored
@@ -52,7 +52,7 @@ SDLDevice::SDLDevice(DeviceSpecs specs, int buffersize) :
|
||||
if(specs.channels == CHANNELS_INVALID)
|
||||
specs.channels = CHANNELS_STEREO;
|
||||
if(specs.format == FORMAT_INVALID)
|
||||
specs.format = FORMAT_S16;
|
||||
specs.format = FORMAT_FLOAT32;
|
||||
if(specs.rate == RATE_INVALID)
|
||||
specs.rate = RATE_48000;
|
||||
|
||||
@@ -61,10 +61,25 @@ SDLDevice::SDLDevice(DeviceSpecs specs, int buffersize) :
|
||||
SDL_AudioSpec format, obtained;
|
||||
|
||||
format.freq = m_specs.rate;
|
||||
if(m_specs.format == FORMAT_U8)
|
||||
switch(m_specs.format)
|
||||
{
|
||||
case FORMAT_U8:
|
||||
format.format = AUDIO_U8;
|
||||
else
|
||||
break;
|
||||
case FORMAT_S16:
|
||||
format.format = AUDIO_S16SYS;
|
||||
break;
|
||||
case FORMAT_S32:
|
||||
format.format = AUDIO_S32SYS;
|
||||
break;
|
||||
case FORMAT_FLOAT32:
|
||||
format.format = AUDIO_F32SYS;
|
||||
break;
|
||||
default:
|
||||
format.format = AUDIO_F32SYS;
|
||||
break;
|
||||
}
|
||||
|
||||
format.channels = m_specs.channels;
|
||||
format.samples = buffersize;
|
||||
format.callback = SDLDevice::SDL_mix;
|
||||
@@ -75,14 +90,25 @@ SDLDevice::SDLDevice(DeviceSpecs specs, int buffersize) :
|
||||
|
||||
m_specs.rate = (SampleRate)obtained.freq;
|
||||
m_specs.channels = (Channels)obtained.channels;
|
||||
if(obtained.format == AUDIO_U8)
|
||||
m_specs.format = FORMAT_U8;
|
||||
else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
|
||||
m_specs.format = FORMAT_S16;
|
||||
else
|
||||
|
||||
switch(obtained.format)
|
||||
{
|
||||
case AUDIO_U8:
|
||||
m_specs.format = FORMAT_U8;
|
||||
break;
|
||||
case AUDIO_S16SYS:
|
||||
m_specs.format = FORMAT_S16;
|
||||
break;
|
||||
case AUDIO_S32SYS:
|
||||
m_specs.format = FORMAT_S32;
|
||||
break;
|
||||
case AUDIO_F32SYS:
|
||||
m_specs.format = FORMAT_FLOAT32;
|
||||
break;
|
||||
default:
|
||||
SDL_CloseAudio();
|
||||
AUD_THROW(DeviceException, "The sample format obtained from SDL is not supported.");
|
||||
break;
|
||||
}
|
||||
|
||||
create();
|
||||
|
@@ -84,7 +84,7 @@ def update_script_node(node, report):
|
||||
if script.is_in_memory or script.is_dirty or script.is_modified or not os.path.exists(osl_path):
|
||||
# write text datablock contents to temporary file
|
||||
osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=False)
|
||||
osl_file.write(script.as_string())
|
||||
osl_file.write(script.as_string() + "\n")
|
||||
osl_file.close()
|
||||
|
||||
ok, oso_path = osl_compile(osl_file.name, report)
|
||||
|
@@ -384,16 +384,16 @@ static ShaderNode *add_node(Scene *scene,
|
||||
|
||||
switch (b_aniso_node.distribution()) {
|
||||
case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
|
||||
aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
|
||||
aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
|
||||
break;
|
||||
case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
|
||||
aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
|
||||
aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
|
||||
break;
|
||||
case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
|
||||
aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID;
|
||||
aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
|
||||
break;
|
||||
case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
|
||||
aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
|
||||
aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -1903,7 +1903,15 @@ string OpenCLDevice::kernel_build_options(const string *debug_src)
|
||||
int version_major, version_minor;
|
||||
if (OpenCLInfo::get_device_version(cdDevice, &version_major, &version_minor)) {
|
||||
if (version_major >= 2) {
|
||||
build_options += "-cl-std=CL2.0 ";
|
||||
/* This appears to trigger a driver bug in Radeon RX cards, so we
|
||||
* don't use OpenCL 2.0 for those. */
|
||||
string device_name = OpenCLInfo::get_readable_device_name(cdDevice);
|
||||
if (!(string_startswith(device_name, "Radeon RX 4") ||
|
||||
string_startswith(device_name, "Radeon (TM) RX 4") ||
|
||||
string_startswith(device_name, "Radeon RX 5") ||
|
||||
string_startswith(device_name, "Radeon (TM) RX 5"))) {
|
||||
build_options += "-cl-std=CL2.0 ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -229,8 +229,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
label = bsdf_microfacet_ggx_sample(kg,
|
||||
sc,
|
||||
@@ -281,7 +279,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
|
||||
&sd->lcg_state);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
|
||||
label = bsdf_microfacet_beckmann_sample(kg,
|
||||
sc,
|
||||
@@ -298,7 +295,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
|
||||
pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
|
||||
label = bsdf_ashikhmin_shirley_sample(sc,
|
||||
sd->Ng,
|
||||
sd->I,
|
||||
@@ -504,8 +500,6 @@ ccl_device_inline
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
@@ -519,12 +513,10 @@ ccl_device_inline
|
||||
sc, sd->I, omega_in, pdf, &sd->lcg_state);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
|
||||
eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
|
||||
eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
@@ -595,8 +587,6 @@ ccl_device_inline
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
@@ -610,12 +600,10 @@ ccl_device_inline
|
||||
sc, sd->I, omega_in, pdf, &sd->lcg_state);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
|
||||
eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
|
||||
eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
@@ -679,18 +667,14 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
bsdf_microfacet_ggx_blur(sc, roughness);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
|
||||
bsdf_microfacet_beckmann_blur(sc, roughness);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
|
||||
bsdf_ashikhmin_shirley_blur(sc, roughness);
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
|
||||
@@ -719,18 +703,14 @@ ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b)
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
|
||||
return bsdf_microfacet_merge(a, b);
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
return bsdf_ashikhmin_velvet_merge(a, b);
|
||||
|
@@ -32,20 +32,11 @@ Other than that, the implementation directly follows the paper.
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device int bsdf_ashikhmin_shirley_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL;
|
||||
}
|
||||
|
||||
ccl_device int bsdf_ashikhmin_shirley_aniso_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
|
||||
bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
|
||||
bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL;
|
||||
}
|
||||
|
||||
|
@@ -256,9 +256,7 @@ ccl_device_forceinline float3 reflection_color(const MicrofacetBsdf *bsdf, float
|
||||
{
|
||||
float3 F = make_float3(1.0f, 1.0f, 1.0f);
|
||||
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
|
||||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID ||
|
||||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID);
|
||||
|
||||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
|
||||
if (use_fresnel) {
|
||||
float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
|
||||
|
||||
@@ -311,19 +309,27 @@ ccl_device int bsdf_microfacet_ggx_setup(MicrofacetBsdf *bsdf)
|
||||
bsdf->extra = NULL;
|
||||
|
||||
bsdf->alpha_x = saturate(bsdf->alpha_x);
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
bsdf->alpha_y = saturate(bsdf->alpha_y);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
|
||||
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL;
|
||||
}
|
||||
|
||||
/* Required to maintain OSL interface. */
|
||||
ccl_device int bsdf_microfacet_ggx_isotropic_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
|
||||
return bsdf_microfacet_ggx_setup(bsdf);
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
|
||||
{
|
||||
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
|
||||
|
||||
bsdf->alpha_x = saturate(bsdf->alpha_x);
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
bsdf->alpha_y = saturate(bsdf->alpha_y);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID;
|
||||
|
||||
@@ -361,32 +367,6 @@ ccl_device bool bsdf_microfacet_merge(const ShaderClosure *a, const ShaderClosur
|
||||
(bsdf_a->extra->clearcoat == bsdf_b->extra->clearcoat)));
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_ggx_aniso_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->extra = NULL;
|
||||
|
||||
bsdf->alpha_x = saturate(bsdf->alpha_x);
|
||||
bsdf->alpha_y = saturate(bsdf->alpha_y);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
|
||||
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL;
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
|
||||
{
|
||||
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
|
||||
|
||||
bsdf->alpha_x = saturate(bsdf->alpha_x);
|
||||
bsdf->alpha_y = saturate(bsdf->alpha_y);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID;
|
||||
|
||||
bsdf_microfacet_fresnel_color(sd, bsdf);
|
||||
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL;
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_ggx_refraction_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->extra = NULL;
|
||||
@@ -636,8 +616,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg,
|
||||
*eval = make_float3(1e6f, 1e6f, 1e6f);
|
||||
|
||||
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
|
||||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID ||
|
||||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID);
|
||||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
|
||||
|
||||
/* if fresnel is used, calculate the color with reflection_color(...) */
|
||||
if (use_fresnel) {
|
||||
@@ -811,19 +790,18 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg,
|
||||
ccl_device int bsdf_microfacet_beckmann_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->alpha_x = saturate(bsdf->alpha_x);
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
bsdf->alpha_y = saturate(bsdf->alpha_y);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL;
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_beckmann_aniso_setup(MicrofacetBsdf *bsdf)
|
||||
/* Required to maintain OSL interface. */
|
||||
ccl_device int bsdf_microfacet_beckmann_isotropic_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->alpha_x = saturate(bsdf->alpha_x);
|
||||
bsdf->alpha_y = saturate(bsdf->alpha_y);
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL;
|
||||
return bsdf_microfacet_beckmann_setup(bsdf);
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_beckmann_refraction_setup(MicrofacetBsdf *bsdf)
|
||||
|
@@ -384,32 +384,10 @@ ccl_device int bsdf_microfacet_multi_ggx_common_setup(MicrofacetBsdf *bsdf)
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_multi_ggx_aniso_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
if (is_zero(bsdf->T))
|
||||
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
|
||||
|
||||
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_multi_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf,
|
||||
const ShaderData *sd)
|
||||
{
|
||||
if (is_zero(bsdf->T))
|
||||
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
|
||||
|
||||
bsdf_microfacet_fresnel_color(sd, bsdf);
|
||||
|
||||
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_multi_ggx_setup(MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
if (is_zero(bsdf->T))
|
||||
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
|
||||
|
||||
@@ -418,7 +396,8 @@ ccl_device int bsdf_microfacet_multi_ggx_setup(MicrofacetBsdf *bsdf)
|
||||
|
||||
ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
|
||||
{
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
if (is_zero(bsdf->T))
|
||||
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
|
||||
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
|
||||
|
||||
|
@@ -100,14 +100,14 @@ CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
|
||||
BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley,
|
||||
ashikhmin_shirley_aniso,
|
||||
ashikhmin_shirley,
|
||||
MicrofacetBsdf,
|
||||
LABEL_GLOSSY | LABEL_REFLECT)
|
||||
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N),
|
||||
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T),
|
||||
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x),
|
||||
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y),
|
||||
BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley_aniso)
|
||||
BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE)
|
||||
CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N),
|
||||
@@ -121,42 +121,42 @@ CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
|
||||
CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth),
|
||||
BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXIsotropic,
|
||||
microfacet_ggx_isotropic,
|
||||
MicrofacetBsdf,
|
||||
LABEL_GLOSSY | LABEL_REFLECT)
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetGGXIsotropicClosure, params.N),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetGGXIsotropicClosure, params.alpha_x),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetGGXIsotropic, microfacet_ggx_isotropic)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX,
|
||||
microfacet_ggx,
|
||||
MicrofacetBsdf,
|
||||
LABEL_GLOSSY | LABEL_REFLECT)
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.T),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_y),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso,
|
||||
microfacet_ggx_aniso,
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannIsotropic,
|
||||
microfacet_beckmann_isotropic,
|
||||
MicrofacetBsdf,
|
||||
LABEL_GLOSSY | LABEL_REFLECT)
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.T),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_x),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_y),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso)
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannIsotropicClosure, params.N),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannIsotropicClosure, params.alpha_x),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannIsotropic, microfacet_beckmann_isotropic)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann,
|
||||
microfacet_beckmann,
|
||||
MicrofacetBsdf,
|
||||
LABEL_GLOSSY | LABEL_REFLECT)
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.T),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_y),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso,
|
||||
microfacet_beckmann_aniso,
|
||||
MicrofacetBsdf,
|
||||
LABEL_GLOSSY | LABEL_REFLECT)
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.T),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_x),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_y),
|
||||
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso)
|
||||
|
||||
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction,
|
||||
microfacet_ggx_refraction,
|
||||
MicrofacetBsdf,
|
||||
@@ -362,13 +362,16 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
|
||||
id++,
|
||||
closure_bsdf_transparent_params(),
|
||||
closure_bsdf_transparent_prepare);
|
||||
|
||||
register_closure(
|
||||
ss, "microfacet_ggx", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
|
||||
ss, "microfacet", id++, closure_bsdf_microfacet_params(), closure_bsdf_microfacet_prepare);
|
||||
register_closure(ss,
|
||||
"microfacet_ggx_aniso",
|
||||
"microfacet_ggx",
|
||||
id++,
|
||||
bsdf_microfacet_ggx_aniso_params(),
|
||||
bsdf_microfacet_ggx_aniso_prepare);
|
||||
bsdf_microfacet_ggx_isotropic_params(),
|
||||
bsdf_microfacet_ggx_isotropic_prepare);
|
||||
register_closure(
|
||||
ss, "microfacet_ggx_aniso", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
|
||||
register_closure(ss,
|
||||
"microfacet_ggx_refraction",
|
||||
id++,
|
||||
@@ -417,13 +420,13 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
|
||||
register_closure(ss,
|
||||
"microfacet_beckmann",
|
||||
id++,
|
||||
bsdf_microfacet_beckmann_params(),
|
||||
bsdf_microfacet_beckmann_prepare);
|
||||
bsdf_microfacet_beckmann_isotropic_params(),
|
||||
bsdf_microfacet_beckmann_isotropic_prepare);
|
||||
register_closure(ss,
|
||||
"microfacet_beckmann_aniso",
|
||||
id++,
|
||||
bsdf_microfacet_beckmann_aniso_params(),
|
||||
bsdf_microfacet_beckmann_aniso_prepare);
|
||||
bsdf_microfacet_beckmann_params(),
|
||||
bsdf_microfacet_beckmann_prepare);
|
||||
register_closure(ss,
|
||||
"microfacet_beckmann_refraction",
|
||||
id++,
|
||||
@@ -432,8 +435,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
|
||||
register_closure(ss,
|
||||
"ashikhmin_shirley",
|
||||
id++,
|
||||
bsdf_ashikhmin_shirley_aniso_params(),
|
||||
bsdf_ashikhmin_shirley_aniso_prepare);
|
||||
bsdf_ashikhmin_shirley_params(),
|
||||
bsdf_ashikhmin_shirley_prepare);
|
||||
register_closure(
|
||||
ss, "ashikhmin_velvet", id++, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
|
||||
register_closure(
|
||||
@@ -508,6 +511,82 @@ bool CBSDFClosure::skip(const ShaderData *sd, int path_flag, int scattering)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Standard Microfacet Closure */
|
||||
|
||||
class MicrofacetClosure : public CBSDFClosure {
|
||||
public:
|
||||
MicrofacetBsdf params;
|
||||
ustring distribution;
|
||||
int refract;
|
||||
|
||||
void setup(ShaderData *sd, int path_flag, float3 weight)
|
||||
{
|
||||
static ustring u_ggx("ggx");
|
||||
static ustring u_default("default");
|
||||
|
||||
const int label = (refract) ? LABEL_TRANSMIT : LABEL_REFLECT;
|
||||
if (skip(sd, path_flag, LABEL_GLOSSY | label)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
|
||||
sd, sizeof(MicrofacetBsdf), weight, ¶ms);
|
||||
|
||||
if (!bsdf) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* GGX */
|
||||
if (distribution == u_ggx || distribution == u_default) {
|
||||
if (!refract) {
|
||||
if (params.alpha_x == params.alpha_y) {
|
||||
/* Isotropic */
|
||||
sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf);
|
||||
}
|
||||
else {
|
||||
/* Anisotropic */
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
|
||||
}
|
||||
}
|
||||
/* Beckmann */
|
||||
else {
|
||||
if (!refract) {
|
||||
if (params.alpha_x == params.alpha_y) {
|
||||
/* Isotropic */
|
||||
sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf);
|
||||
}
|
||||
else {
|
||||
/* Anisotropic */
|
||||
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bsdf_microfacet_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_STRING_PARAM(MicrofacetClosure, distribution),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetClosure, params.N),
|
||||
CLOSURE_FLOAT3_PARAM(MicrofacetClosure, params.T),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_x),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_y),
|
||||
CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.ior),
|
||||
CLOSURE_INT_PARAM(MicrofacetClosure, refract),
|
||||
CLOSURE_STRING_KEYPARAM(MicrofacetClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(MicrofacetClosure)};
|
||||
|
||||
return params;
|
||||
}
|
||||
CCLOSURE_PREPARE(closure_bsdf_microfacet_prepare, MicrofacetClosure)
|
||||
|
||||
/* GGX closures with Fresnel */
|
||||
|
||||
class MicrofacetFresnelClosure : public CBSDFClosure {
|
||||
@@ -582,7 +661,7 @@ class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure {
|
||||
return;
|
||||
}
|
||||
|
||||
sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
|
||||
sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -676,7 +755,7 @@ class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure {
|
||||
}
|
||||
|
||||
bsdf->ior = 0.0f;
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -801,7 +880,7 @@ class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosu
|
||||
return;
|
||||
}
|
||||
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -51,6 +51,7 @@ OSL::ClosureParam *closure_bsdf_transparent_params();
|
||||
OSL::ClosureParam *closure_bssrdf_params();
|
||||
OSL::ClosureParam *closure_absorption_params();
|
||||
OSL::ClosureParam *closure_henyey_greenstein_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params();
|
||||
@@ -70,6 +71,7 @@ void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *dat
|
||||
void closure_bssrdf_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_absorption_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_henyey_greenstein_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_glass_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_aniso_prepare(OSL::RendererServices *, int id, void *data);
|
||||
|
@@ -320,9 +320,9 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
|
||||
/* setup bsdf */
|
||||
if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID ||
|
||||
roughness <= 0.075f) /* use single-scatter GGX */
|
||||
sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
|
||||
sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
|
||||
else /* use multi-scatter GGX */
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
|
||||
}
|
||||
}
|
||||
# ifdef __CAUSTICS_TRICKS__
|
||||
@@ -515,12 +515,34 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
|
||||
float roughness = sqr(param1);
|
||||
|
||||
bsdf->N = N;
|
||||
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
|
||||
bsdf->alpha_x = roughness;
|
||||
bsdf->alpha_y = roughness;
|
||||
bsdf->ior = 0.0f;
|
||||
bsdf->extra = NULL;
|
||||
|
||||
if (data_node.y == SVM_STACK_INVALID) {
|
||||
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
|
||||
bsdf->alpha_x = roughness;
|
||||
bsdf->alpha_y = roughness;
|
||||
}
|
||||
else {
|
||||
bsdf->T = stack_load_float3(stack, data_node.y);
|
||||
|
||||
/* rotate tangent */
|
||||
float rotation = stack_load_float(stack, data_node.z);
|
||||
if (rotation != 0.0f)
|
||||
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
|
||||
|
||||
/* compute roughness */
|
||||
float anisotropy = clamp(param2, -0.99f, 0.99f);
|
||||
if (anisotropy < 0.0f) {
|
||||
bsdf->alpha_x = roughness / (1.0f + anisotropy);
|
||||
bsdf->alpha_y = roughness * (1.0f + anisotropy);
|
||||
}
|
||||
else {
|
||||
bsdf->alpha_x = roughness * (1.0f - anisotropy);
|
||||
bsdf->alpha_y = roughness / (1.0f - anisotropy);
|
||||
}
|
||||
}
|
||||
|
||||
/* setup bsdf */
|
||||
if (type == CLOSURE_BSDF_REFLECTION_ID)
|
||||
sd->flag |= bsdf_reflection_setup(bsdf);
|
||||
@@ -529,10 +551,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
|
||||
else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID)
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
|
||||
kernel_assert(stack_valid(data_node.z));
|
||||
kernel_assert(stack_valid(data_node.w));
|
||||
bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
|
||||
if (bsdf->extra) {
|
||||
bsdf->extra->color = stack_load_float3(stack, data_node.z);
|
||||
bsdf->extra->color = stack_load_float3(stack, data_node.w);
|
||||
bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
|
||||
bsdf->extra->clearcoat = 0.0f;
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
|
||||
@@ -675,64 +697,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID:
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
|
||||
#ifdef __CAUSTICS_TRICKS__
|
||||
if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
#endif
|
||||
float3 weight = sd->svm_closure_weight * mix_weight;
|
||||
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
|
||||
|
||||
if (bsdf) {
|
||||
bsdf->N = N;
|
||||
bsdf->extra = NULL;
|
||||
bsdf->T = stack_load_float3(stack, data_node.y);
|
||||
|
||||
/* rotate tangent */
|
||||
float rotation = stack_load_float(stack, data_node.z);
|
||||
|
||||
if (rotation != 0.0f)
|
||||
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
|
||||
|
||||
/* compute roughness */
|
||||
float roughness = sqr(param1);
|
||||
float anisotropy = clamp(param2, -0.99f, 0.99f);
|
||||
|
||||
if (anisotropy < 0.0f) {
|
||||
bsdf->alpha_x = roughness / (1.0f + anisotropy);
|
||||
bsdf->alpha_y = roughness * (1.0f + anisotropy);
|
||||
}
|
||||
else {
|
||||
bsdf->alpha_x = roughness * (1.0f - anisotropy);
|
||||
bsdf->alpha_y = roughness / (1.0f - anisotropy);
|
||||
}
|
||||
|
||||
bsdf->ior = 0.0f;
|
||||
|
||||
if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) {
|
||||
sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf);
|
||||
}
|
||||
else if (type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) {
|
||||
sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf);
|
||||
}
|
||||
else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) {
|
||||
kernel_assert(stack_valid(data_node.w));
|
||||
bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
|
||||
if (bsdf->extra) {
|
||||
bsdf->extra->color = stack_load_float3(stack, data_node.w);
|
||||
bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
|
||||
bsdf->extra->clearcoat = 0.0f;
|
||||
sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
|
||||
}
|
||||
}
|
||||
else
|
||||
sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
|
||||
float3 weight = sd->svm_closure_weight * mix_weight;
|
||||
VelvetBsdf *bsdf = (VelvetBsdf *)bsdf_alloc(sd, sizeof(VelvetBsdf), weight);
|
||||
|
@@ -539,12 +539,6 @@ typedef enum ClosureType {
|
||||
CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID,
|
||||
CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID,
|
||||
CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID,
|
||||
CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID,
|
||||
CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID,
|
||||
CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID,
|
||||
CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_FRESNEL_ID,
|
||||
CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID,
|
||||
CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID,
|
||||
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
|
||||
CLOSURE_BSDF_PHONG_RAMP_ID,
|
||||
CLOSURE_BSDF_GLOSSY_TOON_ID,
|
||||
@@ -605,10 +599,9 @@ typedef enum ClosureType {
|
||||
#define CLOSURE_IS_BSDF_TRANSPARENT(type) (type == CLOSURE_BSDF_TRANSPARENT_ID)
|
||||
#define CLOSURE_IS_BSDF_MULTISCATTER(type) \
|
||||
(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID || \
|
||||
type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID || \
|
||||
type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)
|
||||
#define CLOSURE_IS_BSDF_MICROFACET(type) \
|
||||
((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) || \
|
||||
((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID) || \
|
||||
(type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && \
|
||||
type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) || \
|
||||
(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID))
|
||||
@@ -616,8 +609,7 @@ typedef enum ClosureType {
|
||||
(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID || \
|
||||
type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID || \
|
||||
type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || \
|
||||
type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID || \
|
||||
type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID)
|
||||
type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID)
|
||||
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
|
||||
#define CLOSURE_IS_BSSRDF(type) \
|
||||
(type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
|
||||
|
@@ -2166,12 +2166,11 @@ NODE_DEFINE(AnisotropicBsdfNode)
|
||||
SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
|
||||
|
||||
static NodeEnum distribution_enum;
|
||||
distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID);
|
||||
distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
|
||||
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID);
|
||||
distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID);
|
||||
SOCKET_ENUM(
|
||||
distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
|
||||
distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
|
||||
distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
|
||||
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
|
||||
distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
|
||||
SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
|
||||
|
||||
SOCKET_IN_VECTOR(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
|
||||
|
||||
@@ -2186,7 +2185,7 @@ NODE_DEFINE(AnisotropicBsdfNode)
|
||||
|
||||
AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(node_type)
|
||||
{
|
||||
closure = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
|
||||
closure = CLOSURE_BSDF_MICROFACET_GGX_ID;
|
||||
}
|
||||
|
||||
void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||
@@ -2205,7 +2204,7 @@ void AnisotropicBsdfNode::compile(SVMCompiler &compiler)
|
||||
{
|
||||
closure = distribution;
|
||||
|
||||
if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID)
|
||||
if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID)
|
||||
BsdfNode::compile(
|
||||
compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color"));
|
||||
else
|
||||
@@ -2299,7 +2298,7 @@ void GlossyBsdfNode::compile(SVMCompiler &compiler)
|
||||
if (closure == CLOSURE_BSDF_REFLECTION_ID)
|
||||
BsdfNode::compile(compiler, NULL, NULL);
|
||||
else if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID)
|
||||
BsdfNode::compile(compiler, input("Roughness"), NULL, input("Color"));
|
||||
BsdfNode::compile(compiler, input("Roughness"), NULL, NULL, input("Color"));
|
||||
else
|
||||
BsdfNode::compile(compiler, input("Roughness"), NULL);
|
||||
}
|
||||
|
@@ -411,17 +411,17 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
|
||||
NSTIFFPboardType,
|
||||
nil]];
|
||||
|
||||
if (state != GHOST_kWindowStateFullScreen) {
|
||||
if (is_dialog && parentWindow) {
|
||||
[parentWindow->getCocoaWindow() addChildWindow:m_window ordered:NSWindowAbove];
|
||||
[m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
|
||||
}
|
||||
else if (state != GHOST_kWindowStateFullScreen) {
|
||||
[m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
}
|
||||
|
||||
if (state == GHOST_kWindowStateFullScreen)
|
||||
setState(GHOST_kWindowStateFullScreen);
|
||||
|
||||
if (is_dialog && parentWindow) {
|
||||
[parentWindow->getCocoaWindow() addChildWindow:m_window ordered:NSWindowAbove];
|
||||
}
|
||||
|
||||
setNativePixelSize();
|
||||
|
||||
[pool drain];
|
||||
|
Binary file not shown.
Binary file not shown.
@@ -16,4 +16,4 @@ if [ -n "$XDG_RUNTIME_DIR" ]; then
|
||||
fi
|
||||
|
||||
# Run Blender
|
||||
$SNAP/blender
|
||||
$SNAP/blender "$@"
|
||||
|
@@ -486,7 +486,10 @@ class CLIP_OT_constraint_to_fcurve(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
# Find start and end frames.
|
||||
if con.object:
|
||||
if con.type == 'CAMERA_SOLVER':
|
||||
# Camera solver constraint is always referring to camera.
|
||||
tracks = clip.tracking.tracks
|
||||
elif con.object:
|
||||
tracking_object = clip.tracking.objects.get(con.object, None)
|
||||
if not tracking_object:
|
||||
self.report({'ERROR'}, "Motion Tracking object not found")
|
||||
|
@@ -6768,7 +6768,10 @@ class VIEW3D_PT_overlay_gpencil_options(Panel):
|
||||
|
||||
if context.object.mode in {'PAINT_GPENCIL', 'VERTEX_GPENCIL'}:
|
||||
layout.label(text="Vertex Paint")
|
||||
layout.prop(overlay, "gpencil_vertex_paint_opacity", text="Opacity", slider=True)
|
||||
row = layout.row()
|
||||
shading = VIEW3D_PT_shading.get_shading(context)
|
||||
row.enabled = shading.type not in {'WIREFRAME', 'RENDERED'}
|
||||
row.prop(overlay, "gpencil_vertex_paint_opacity", text="Opacity", slider=True)
|
||||
|
||||
|
||||
class VIEW3D_PT_quad_view(Panel):
|
||||
|
@@ -30,13 +30,13 @@
|
||||
/* Blender major and minor version. */
|
||||
#define BLENDER_VERSION 283
|
||||
/* Blender patch version for bugfix releases. */
|
||||
#define BLENDER_VERSION_PATCH 0
|
||||
#define BLENDER_VERSION_PATCH 2
|
||||
/** Blender release cycle stage: alpha/beta/rc/release. */
|
||||
#define BLENDER_VERSION_CYCLE release
|
||||
#define BLENDER_VERSION_CYCLE beta
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 18
|
||||
#define BLENDER_FILE_SUBVERSION 19
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
@@ -41,6 +41,7 @@ struct Object;
|
||||
struct Scene;
|
||||
struct SpaceImage;
|
||||
struct ToolSettings;
|
||||
struct ViewLayer;
|
||||
struct bDeformGroup;
|
||||
struct bGPDframe;
|
||||
struct bGPDlayer;
|
||||
@@ -253,7 +254,8 @@ typedef void (*gpIterCb)(struct bGPDlayer *layer,
|
||||
struct bGPDstroke *stroke,
|
||||
void *thunk);
|
||||
|
||||
void BKE_gpencil_visible_stroke_iter(struct Object *ob,
|
||||
void BKE_gpencil_visible_stroke_iter(struct ViewLayer *view_layer,
|
||||
struct Object *ob,
|
||||
gpIterCb layer_cb,
|
||||
gpIterCb stroke_cb,
|
||||
void *thunk,
|
||||
|
@@ -477,6 +477,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
Material *ma = BLI_findstring(&bmain->materials, "Dots Stroke", offsetof(ID, name) + 2);
|
||||
if (ma == NULL) {
|
||||
ma = BKE_gpencil_material_add(bmain, "Dots Stroke");
|
||||
ma->gp_style->mode = GP_MATERIAL_MODE_DOT;
|
||||
}
|
||||
brush->gpencil_settings->material = ma;
|
||||
/* Pin the matterial to the brush. */
|
||||
@@ -701,6 +702,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
Material *ma = BLI_findstring(&bmain->materials, "Dots Stroke", offsetof(ID, name) + 2);
|
||||
if (ma == NULL) {
|
||||
ma = BKE_gpencil_material_add(bmain, "Dots Stroke");
|
||||
ma->gp_style->mode = GP_MATERIAL_MODE_DOT;
|
||||
}
|
||||
brush->gpencil_settings->material = ma;
|
||||
/* Pin the matterial to the brush. */
|
||||
|
@@ -824,12 +824,7 @@ bool BKE_gpencil_layer_is_editable(const bGPDlayer *gpl)
|
||||
|
||||
/* Layer must be: Visible + Editable */
|
||||
if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0) {
|
||||
/* Opacity must be sufficiently high that it is still "visible"
|
||||
* Otherwise, it's not really "visible" to the user, so no point editing...
|
||||
*/
|
||||
if (gpl->opacity > GPENCIL_ALPHA_OPACITY_THRESH) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Something failed */
|
||||
@@ -1832,6 +1827,29 @@ bool BKE_gpencil_from_image(SpaceImage *sima, bGPDframe *gpf, const float size,
|
||||
return done;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to check if a layers is used as mask
|
||||
* \param gpd Grease pencil datablock
|
||||
* \param gpl_mask Actual Layer
|
||||
* \return True if the layer is a mask
|
||||
*/
|
||||
static bool gpencil_is_layer_mask(ViewLayer *view_layer, bGPdata *gpd, bGPDlayer *gpl_mask)
|
||||
{
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
if ((gpl->viewlayername[0] != '\0') && (!STREQ(view_layer->name, gpl->viewlayername))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl->mask_layers) {
|
||||
if (STREQ(gpl_mask->info, mask->name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Iterators
|
||||
*
|
||||
@@ -1840,8 +1858,13 @@ bool BKE_gpencil_from_image(SpaceImage *sima, bGPDframe *gpf, const float size,
|
||||
*
|
||||
* \{ */
|
||||
|
||||
void BKE_gpencil_visible_stroke_iter(
|
||||
Object *ob, gpIterCb layer_cb, gpIterCb stroke_cb, void *thunk, bool do_onion, int cfra)
|
||||
void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer,
|
||||
Object *ob,
|
||||
gpIterCb layer_cb,
|
||||
gpIterCb stroke_cb,
|
||||
void *thunk,
|
||||
bool do_onion,
|
||||
int cfra)
|
||||
{
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
const bool is_multiedit = GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
|
||||
@@ -1863,6 +1886,18 @@ void BKE_gpencil_visible_stroke_iter(
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Hide the layer if it's defined a view layer filter. This is used to
|
||||
* generate renders, putting only selected GP layers for each View Layer.
|
||||
* This is used only in final render and never in Viewport. */
|
||||
if ((view_layer != NULL) && (gpl->viewlayername[0] != '\0') &&
|
||||
(!STREQ(view_layer->name, gpl->viewlayername))) {
|
||||
/* If the layer is used as mask, cannot be filtered or the masking system
|
||||
* will crash because needs the mask layer in the draw pipeline. */
|
||||
if (!gpencil_is_layer_mask(view_layer, gpd, gpl)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_multiedit) {
|
||||
sta_gpf = end_gpf = NULL;
|
||||
/* Check the whole range and tag the editable frames. */
|
||||
|
@@ -177,6 +177,16 @@ static void lib_id_library_local_paths(Main *bmain, Library *lib, ID *id)
|
||||
(void *)bpath_user_data);
|
||||
}
|
||||
|
||||
static int lib_id_clear_library_data_users_update_cb(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
ID *id = cb_data->user_data;
|
||||
if (*cb_data->id_pointer == id) {
|
||||
DEG_id_tag_update(cb_data->id_owner, ID_RECALC_TAG_FOR_UNDO);
|
||||
return IDWALK_RET_STOP_ITER;
|
||||
}
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull an ID out of a library (make it local). Only call this for IDs that
|
||||
* don't have other library users.
|
||||
@@ -199,6 +209,21 @@ static void lib_id_clear_library_data_ex(Main *bmain, ID *id)
|
||||
}
|
||||
}
|
||||
|
||||
/* Conceptually, an ID made local is not the same as the linked one anymore. Reflect that by
|
||||
* regenerating its session UUID. */
|
||||
BKE_lib_libblock_session_uuid_renew(id);
|
||||
|
||||
/* We need to tag this IDs and all of its users, conceptually new local ID and original linked
|
||||
* ones are two completely different data-blocks that were virtually remaped, even though in
|
||||
* reality they remain the same data. For undo this info is critical now. */
|
||||
DEG_id_tag_update_ex(bmain, id, ID_RECALC_COPY_ON_WRITE);
|
||||
ID *id_iter;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
|
||||
BKE_library_foreach_ID_link(
|
||||
bmain, id_iter, lib_id_clear_library_data_users_update_cb, id, IDWALK_READONLY);
|
||||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
|
||||
/* Internal shape key blocks inside data-blocks also stores id->lib,
|
||||
* make sure this stays in sync (note that we do not need any explicit handling for real EMBEDDED
|
||||
* IDs here, this is down automatically in `lib_id_expand_local_cb()`. */
|
||||
@@ -1101,8 +1126,10 @@ void BKE_lib_libblock_session_uuid_ensure(ID *id)
|
||||
/**
|
||||
* Re-generate a new session-wise uuid for the given \a id.
|
||||
*
|
||||
* \warning This has a very specific use-case (to handle UI-related data-blocks that are kept
|
||||
* across new file reading, when we do keep existing UI). No other usage is expected currently.
|
||||
* \warning This has a few very specific use-cases, no other usage is expected currently:
|
||||
* - To handle UI-related data-blocks that are kept across new file reading, when we do keep
|
||||
* existing UI.
|
||||
* - For IDs that are made local without needing any copying.
|
||||
*/
|
||||
void BKE_lib_libblock_session_uuid_renew(ID *id)
|
||||
{
|
||||
|
@@ -2342,7 +2342,9 @@ MINLINE float color_balance_fl(
|
||||
x = 0.f;
|
||||
}
|
||||
|
||||
return powf(x, gamma) * mul;
|
||||
x = powf(x, gamma) * mul;
|
||||
CLAMP(x, FLT_MIN, FLT_MAX);
|
||||
return x;
|
||||
}
|
||||
|
||||
static void make_cb_table_float(float lift, float gain, float gamma, float *table, float mul)
|
||||
|
@@ -4220,7 +4220,19 @@ static float mean_value_half_tan_v2(const struct Float2_Len *d_curr,
|
||||
|
||||
void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
|
||||
{
|
||||
const float eps = 1e-5f; /* take care, low values cause [#36105] */
|
||||
/* Before starting to calculate the weight, we need to figure out the floating point precision we
|
||||
* can expect from the supplied data. */
|
||||
float max_value = 0;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
max_value = max_ff(max_value, fabsf(v[i][0] - co[0]));
|
||||
max_value = max_ff(max_value, fabsf(v[i][1] - co[1]));
|
||||
max_value = max_ff(max_value, fabsf(v[i][2] - co[2]));
|
||||
}
|
||||
|
||||
/* These to values we derived by empirically testing different values that works for the test
|
||||
* files in D7772. */
|
||||
const float eps = 16.0f * FLT_EPSILON * max_value;
|
||||
const float eps_sq = eps * eps;
|
||||
const float *v_curr, *v_next;
|
||||
float ht_prev, ht; /* half tangents */
|
||||
@@ -4293,8 +4305,20 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
|
||||
|
||||
void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
|
||||
{
|
||||
const float eps = 1e-5f; /* take care, low values cause [#36105] */
|
||||
/* Before starting to calculate the weight, we need to figure out the floating point precision we
|
||||
* can expect from the supplied data. */
|
||||
float max_value = 0;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
max_value = max_ff(max_value, fabsf(v[i][0] - co[0]));
|
||||
max_value = max_ff(max_value, fabsf(v[i][1] - co[1]));
|
||||
}
|
||||
|
||||
/* These to values we derived by empirically testing different values that works for the test
|
||||
* files in D7772. */
|
||||
const float eps = 16.0f * FLT_EPSILON * max_value;
|
||||
const float eps_sq = eps * eps;
|
||||
|
||||
const float *v_curr, *v_next;
|
||||
float ht_prev, ht; /* half tangents */
|
||||
float totweight = 0.0f;
|
||||
|
@@ -1222,6 +1222,10 @@ static int fd_read_from_memfile(FileData *filedata,
|
||||
static MemFileChunk *chunk = NULL;
|
||||
size_t chunkoffset, readsize, totread;
|
||||
|
||||
if (r_is_memchunck_identical != NULL) {
|
||||
*r_is_memchunck_identical = true;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1272,13 +1276,13 @@ static int fd_read_from_memfile(FileData *filedata,
|
||||
filedata->file_offset += readsize;
|
||||
seek += readsize;
|
||||
if (r_is_memchunck_identical != NULL) {
|
||||
/* `is_identical` of current chunk represent whether it changed compared to previous undo
|
||||
/* `is_identical` of current chunk represents whether it changed compared to previous undo
|
||||
* step. this is fine in redo case (filedata->undo_direction > 0), but not in undo case,
|
||||
* where we need an extra flag defined when saving the next (future) step after the one we
|
||||
* want to restore, as we are supposed to 'come from' that future undo step, and not the
|
||||
* one before current one. */
|
||||
*r_is_memchunck_identical = filedata->undo_direction > 0 ? chunk->is_identical :
|
||||
chunk->is_identical_future;
|
||||
*r_is_memchunck_identical &= filedata->undo_direction > 0 ? chunk->is_identical :
|
||||
chunk->is_identical_future;
|
||||
}
|
||||
} while (totread < size);
|
||||
|
||||
|
@@ -309,6 +309,7 @@ data_to_c_simple(engines/basic/shaders/conservative_depth_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/antialiasing_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/antialiasing_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_dof_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_dof_solid_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_envelope_outline_vert.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_envelope_solid_frag.glsl SRC)
|
||||
data_to_c_simple(engines/overlay/shaders/armature_envelope_solid_vert.glsl SRC)
|
||||
|
@@ -265,8 +265,10 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
|
||||
GPENCIL_VERTEX_MODE(gpd) || pd->is_render;
|
||||
bool is_masked = (gpl->flag & GP_LAYER_USE_MASK) && !BLI_listbase_is_empty(&gpl->mask_layers);
|
||||
|
||||
float vert_col_opacity = (overide_vertcol) ? (is_vert_col_mode ? 1.0f : 0.0f) :
|
||||
gpl->vertex_paint_opacity;
|
||||
float vert_col_opacity = (overide_vertcol) ?
|
||||
(is_vert_col_mode ? pd->vertex_paint_opacity : 0.0f) :
|
||||
pd->is_render ? gpl->vertex_paint_opacity :
|
||||
pd->vertex_paint_opacity;
|
||||
/* Negate thickness sign to tag that strokes are in screen space.
|
||||
* Convert to world units (by default, 1 meter = 2000 px). */
|
||||
float thickness_scale = (is_screenspace) ? -1.0f : (gpd->pixfactor / GPENCIL_PIXEL_FACTOR);
|
||||
|
@@ -91,6 +91,7 @@ void GPENCIL_engine_init(void *ved)
|
||||
stl->pd->gp_object_pool = vldata->gp_object_pool;
|
||||
stl->pd->gp_layer_pool = vldata->gp_layer_pool;
|
||||
stl->pd->gp_vfx_pool = vldata->gp_vfx_pool;
|
||||
stl->pd->view_layer = ctx->view_layer;
|
||||
stl->pd->scene = ctx->scene;
|
||||
stl->pd->v3d = ctx->v3d;
|
||||
stl->pd->last_light_pool = NULL;
|
||||
@@ -223,6 +224,7 @@ void GPENCIL_cache_init(void *ved)
|
||||
const bool is_fade_layer = ((!hide_overlay) && (!pd->is_render) &&
|
||||
(draw_ctx->v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS));
|
||||
pd->fade_layer_opacity = (is_fade_layer) ? draw_ctx->v3d->overlay.gpencil_fade_layer : -1.0f;
|
||||
pd->vertex_paint_opacity = draw_ctx->v3d->overlay.gpencil_vertex_paint_opacity;
|
||||
/* Fade GPencil Objects. */
|
||||
const bool is_fade_object = ((!hide_overlay) && (!pd->is_render) &&
|
||||
(draw_ctx->v3d->gp_flag & V3D_GP_FADE_OBJECTS) &&
|
||||
@@ -598,6 +600,7 @@ void GPENCIL_cache_populate(void *ved, Object *ob)
|
||||
GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
|
||||
GPENCIL_PrivateData *pd = vedata->stl->pd;
|
||||
GPENCIL_TextureList *txl = vedata->txl;
|
||||
const bool is_final_render = DRW_state_is_image_render();
|
||||
|
||||
/* object must be visible */
|
||||
if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
|
||||
@@ -617,7 +620,8 @@ void GPENCIL_cache_populate(void *ved, Object *ob)
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
bool do_onion = (!pd->is_render) ? pd->do_onion : (gpd->onion_flag & GP_ONION_GHOST_ALWAYS);
|
||||
|
||||
BKE_gpencil_visible_stroke_iter(ob,
|
||||
BKE_gpencil_visible_stroke_iter(is_final_render ? pd->view_layer : NULL,
|
||||
ob,
|
||||
gpencil_layer_cache_populate,
|
||||
gpencil_stroke_cache_populate,
|
||||
&iter,
|
||||
|
@@ -307,6 +307,8 @@ typedef struct GPENCIL_PrivateData {
|
||||
float dof_params[2];
|
||||
/* Used for DoF Setup. */
|
||||
Object *camera;
|
||||
/* Copy of draw_ctx->view_layer for convenience. */
|
||||
struct ViewLayer *view_layer;
|
||||
/* Copy of draw_ctx->scene for convenience. */
|
||||
struct Scene *scene;
|
||||
/* Copy of draw_ctx->vie3d for convenience. */
|
||||
@@ -361,6 +363,8 @@ typedef struct GPENCIL_PrivateData {
|
||||
float xray_alpha;
|
||||
/* Mask invert uniform. */
|
||||
int mask_invert;
|
||||
/* Vertex Paint opacity. */
|
||||
float vertex_paint_opacity;
|
||||
} GPENCIL_PrivateData;
|
||||
|
||||
/* geometry batch cache functions */
|
||||
|
@@ -228,11 +228,12 @@ void OVERLAY_armature_cache_init(OVERLAY_Data *vedata)
|
||||
{
|
||||
format = formats->instance_extra;
|
||||
|
||||
sh = OVERLAY_shader_armature_degrees_of_freedom();
|
||||
sh = OVERLAY_shader_armature_degrees_of_freedom_wire();
|
||||
grp = DRW_shgroup_create(sh, armature_ps);
|
||||
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
|
||||
cb->dof_lines = BUF_INSTANCE(grp, format, DRW_cache_bone_dof_lines_get());
|
||||
|
||||
sh = OVERLAY_shader_armature_degrees_of_freedom_solid();
|
||||
grp = DRW_shgroup_create(sh, armature_transp_ps);
|
||||
DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
|
||||
cb->dof_sphere = BUF_INSTANCE(grp, format, DRW_cache_bone_dof_sphere_get());
|
||||
|
@@ -358,7 +358,7 @@ static void OVERLAY_gpencil_color_names(Object *ob)
|
||||
int cfra = DEG_get_ctime(draw_ctx->depsgraph);
|
||||
|
||||
BKE_gpencil_visible_stroke_iter(
|
||||
ob, NULL, overlay_gpencil_draw_stroke_color_name, ob, false, cfra);
|
||||
NULL, ob, NULL, overlay_gpencil_draw_stroke_color_name, ob, false, cfra);
|
||||
}
|
||||
|
||||
void OVERLAY_gpencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
||||
|
@@ -259,7 +259,7 @@ static void OVERLAY_outline_gpencil(OVERLAY_PrivateData *pd, Object *ob)
|
||||
}
|
||||
|
||||
BKE_gpencil_visible_stroke_iter(
|
||||
ob, gp_layer_cache_populate, gp_stroke_cache_populate, &iter, false, pd->cfra);
|
||||
NULL, ob, gp_layer_cache_populate, gp_stroke_cache_populate, &iter, false, pd->cfra);
|
||||
}
|
||||
|
||||
void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata,
|
||||
|
@@ -562,7 +562,8 @@ void OVERLAY_wireframe_draw(OVERLAY_Data *vedata);
|
||||
void OVERLAY_wireframe_in_front_draw(OVERLAY_Data *vedata);
|
||||
|
||||
GPUShader *OVERLAY_shader_antialiasing(void);
|
||||
GPUShader *OVERLAY_shader_armature_degrees_of_freedom(void);
|
||||
GPUShader *OVERLAY_shader_armature_degrees_of_freedom_wire(void);
|
||||
GPUShader *OVERLAY_shader_armature_degrees_of_freedom_solid(void);
|
||||
GPUShader *OVERLAY_shader_armature_envelope(bool use_outline);
|
||||
GPUShader *OVERLAY_shader_armature_shape(bool use_outline);
|
||||
GPUShader *OVERLAY_shader_armature_shape_wire(void);
|
||||
|
@@ -31,6 +31,7 @@
|
||||
extern char datatoc_antialiasing_frag_glsl[];
|
||||
extern char datatoc_antialiasing_vert_glsl[];
|
||||
extern char datatoc_armature_dof_vert_glsl[];
|
||||
extern char datatoc_armature_dof_solid_frag_glsl[];
|
||||
extern char datatoc_armature_envelope_distance_frag_glsl[];
|
||||
extern char datatoc_armature_envelope_outline_vert_glsl[];
|
||||
extern char datatoc_armature_envelope_solid_frag_glsl[];
|
||||
@@ -130,7 +131,8 @@ extern char datatoc_common_view_lib_glsl[];
|
||||
|
||||
typedef struct OVERLAY_Shaders {
|
||||
GPUShader *antialiasing;
|
||||
GPUShader *armature_dof;
|
||||
GPUShader *armature_dof_wire;
|
||||
GPUShader *armature_dof_solid;
|
||||
GPUShader *armature_envelope_outline;
|
||||
GPUShader *armature_envelope_solid;
|
||||
GPUShader *armature_shape_outline;
|
||||
@@ -473,13 +475,13 @@ GPUShader *OVERLAY_shader_armature_stick(void)
|
||||
return sh_data->armature_stick;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_armature_degrees_of_freedom(void)
|
||||
GPUShader *OVERLAY_shader_armature_degrees_of_freedom_wire(void)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
|
||||
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
|
||||
if (!sh_data->armature_dof) {
|
||||
sh_data->armature_dof = GPU_shader_create_from_arrays({
|
||||
if (!sh_data->armature_dof_wire) {
|
||||
sh_data->armature_dof_wire = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg->lib,
|
||||
datatoc_common_globals_lib_glsl,
|
||||
datatoc_common_view_lib_glsl,
|
||||
@@ -487,10 +489,31 @@ GPUShader *OVERLAY_shader_armature_degrees_of_freedom(void)
|
||||
NULL},
|
||||
.frag =
|
||||
(const char *[]){datatoc_common_view_lib_glsl, datatoc_armature_wire_frag_glsl, NULL},
|
||||
.defs = (const char *[]){sh_cfg->def, "#define EDGE\n", NULL},
|
||||
});
|
||||
}
|
||||
return sh_data->armature_dof_wire;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_armature_degrees_of_freedom_solid(void)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
|
||||
OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
|
||||
if (!sh_data->armature_dof_solid) {
|
||||
sh_data->armature_dof_solid = GPU_shader_create_from_arrays({
|
||||
.vert = (const char *[]){sh_cfg->lib,
|
||||
datatoc_common_globals_lib_glsl,
|
||||
datatoc_common_view_lib_glsl,
|
||||
datatoc_armature_dof_vert_glsl,
|
||||
NULL},
|
||||
.frag = (const char *[]){datatoc_common_view_lib_glsl,
|
||||
datatoc_armature_dof_solid_frag_glsl,
|
||||
NULL},
|
||||
.defs = (const char *[]){sh_cfg->def, NULL},
|
||||
});
|
||||
}
|
||||
return sh_data->armature_dof;
|
||||
return sh_data->armature_dof_solid;
|
||||
}
|
||||
|
||||
GPUShader *OVERLAY_shader_armature_wire(void)
|
||||
|
@@ -0,0 +1,11 @@
|
||||
|
||||
flat in vec4 finalColor;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 1) out vec4 lineOutput;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = finalColor;
|
||||
lineOutput = vec4(0.0);
|
||||
}
|
@@ -8,8 +8,10 @@ in vec4 color;
|
||||
in mat4 inst_obmat;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
#ifdef EDGE
|
||||
flat out vec2 edgeStart;
|
||||
noperspective out vec2 edgePos;
|
||||
#endif
|
||||
|
||||
vec3 sphere_project(float ax, float az)
|
||||
{
|
||||
@@ -35,7 +37,9 @@ void main()
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
finalColor = color;
|
||||
|
||||
#ifdef EDGE
|
||||
edgeStart = edgePos = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy;
|
||||
#endif
|
||||
|
||||
#ifdef USE_WORLD_CLIP_PLANES
|
||||
world_clip_planes_calc_clip_distance(world_pos);
|
||||
|
@@ -162,12 +162,15 @@ void workbench_transparent_draw_depth_pass(WORKBENCH_Data *data)
|
||||
|
||||
if (do_transparent_depth_pass) {
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
|
||||
DRWState state_oit = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_OIT;
|
||||
|
||||
if (!DRW_pass_is_empty(psl->transp_accum_ps)) {
|
||||
GPU_framebuffer_bind(fbl->opaque_fb);
|
||||
/* TODO(fclem) Disable writting to first two buffers. Unecessary waste of bandwidth. */
|
||||
DRW_pass_state_set(psl->transp_accum_ps, state | wpd->cull_state | wpd->clip_state);
|
||||
DRW_draw_pass(psl->transp_accum_ps);
|
||||
/* Set the state back to original. */
|
||||
DRW_pass_state_set(psl->transp_accum_ps, state_oit | wpd->cull_state | wpd->clip_state);
|
||||
}
|
||||
|
||||
if (!DRW_pass_is_empty(psl->transp_accum_infront_ps)) {
|
||||
@@ -175,6 +178,9 @@ void workbench_transparent_draw_depth_pass(WORKBENCH_Data *data)
|
||||
/* TODO(fclem) Disable writting to first two buffers. Unecessary waste of bandwidth. */
|
||||
DRW_pass_state_set(psl->transp_accum_infront_ps, state | wpd->cull_state | wpd->clip_state);
|
||||
DRW_draw_pass(psl->transp_accum_infront_ps);
|
||||
/* Set the state back to original. */
|
||||
DRW_pass_state_set(psl->transp_accum_infront_ps,
|
||||
state_oit | wpd->cull_state | wpd->clip_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -102,6 +102,7 @@ static GpencilBatchCache *gpencil_batch_cache_init(Object *ob, int cfra)
|
||||
|
||||
cache->is_dirty = true;
|
||||
cache->cache_frame = cfra;
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
@@ -385,7 +386,8 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr
|
||||
.vert_len = 1, /* Start at 1 for the gl_InstanceID trick to work (see vert shader). */
|
||||
.tri_len = 0,
|
||||
};
|
||||
BKE_gpencil_visible_stroke_iter(ob, NULL, gp_object_verts_count_cb, &iter, do_onion, cfra);
|
||||
BKE_gpencil_visible_stroke_iter(
|
||||
NULL, ob, NULL, gp_object_verts_count_cb, &iter, do_onion, cfra);
|
||||
|
||||
/* Create VBOs. */
|
||||
GPUVertFormat *format = gpencil_stroke_format();
|
||||
@@ -401,7 +403,7 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfr
|
||||
GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, iter.vert_len);
|
||||
|
||||
/* Fill buffers with data. */
|
||||
BKE_gpencil_visible_stroke_iter(ob, NULL, gpencil_stroke_iter_cb, &iter, do_onion, cfra);
|
||||
BKE_gpencil_visible_stroke_iter(NULL, ob, NULL, gpencil_stroke_iter_cb, &iter, do_onion, cfra);
|
||||
|
||||
/* Mark last 2 verts as invalid. */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
@@ -475,7 +477,7 @@ GPUBatch *DRW_cache_gpencil_face_wireframe_get(Object *ob)
|
||||
|
||||
/* IMPORTANT: Keep in sync with gpencil_edit_batches_ensure() */
|
||||
bool do_onion = true;
|
||||
BKE_gpencil_visible_stroke_iter(ob, NULL, gp_lines_indices_cb, &iter, do_onion, cfra);
|
||||
BKE_gpencil_visible_stroke_iter(NULL, ob, NULL, gp_lines_indices_cb, &iter, do_onion, cfra);
|
||||
|
||||
GPUIndexBuf *ibo = GPU_indexbuf_build(&iter.ibo);
|
||||
|
||||
@@ -724,7 +726,8 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in
|
||||
iter.verts = (gpEditVert *)cache->edit_vbo->data;
|
||||
|
||||
/* Fill buffers with data. */
|
||||
BKE_gpencil_visible_stroke_iter(ob, NULL, gpencil_edit_stroke_iter_cb, &iter, do_onion, cfra);
|
||||
BKE_gpencil_visible_stroke_iter(
|
||||
NULL, ob, NULL, gpencil_edit_stroke_iter_cb, &iter, do_onion, cfra);
|
||||
|
||||
/* Create the batches */
|
||||
cache->edit_points_batch = GPU_batch_create(GPU_PRIM_POINTS, cache->vbo, NULL);
|
||||
|
@@ -8413,7 +8413,11 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *reg
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
/* exported to interface.c: UI_but_active_only() */
|
||||
/**
|
||||
* Exported to interface.c: #UI_but_active_only()
|
||||
* \note The region is only for the button.
|
||||
* The context needs to be set by the caller.
|
||||
*/
|
||||
void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
@@ -8427,10 +8431,7 @@ void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but)
|
||||
event.customdata = but;
|
||||
event.customdatafree = false;
|
||||
|
||||
ARegion *region_ctx = CTX_wm_region(C);
|
||||
CTX_wm_region_set(C, region);
|
||||
ui_do_button(C, but->block, but, &event);
|
||||
CTX_wm_region_set(C, region_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -737,6 +737,8 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||
*r_path = NULL;
|
||||
/* special case for bone constraints */
|
||||
char *path_from_bone = NULL;
|
||||
/* Remove links from the collection list which don't contain 'prop'. */
|
||||
bool ensure_list_items_contain_prop = false;
|
||||
|
||||
/* PropertyGroup objects don't have a reference to the struct that actually owns
|
||||
* them, so it is normally necessary to do a brute force search to find it. This
|
||||
@@ -803,6 +805,8 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||
else {
|
||||
*r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
|
||||
}
|
||||
/* Account for properties only being available for some sequence types. */
|
||||
ensure_list_items_contain_prop = true;
|
||||
}
|
||||
else if (RNA_struct_is_a(ptr->type, &RNA_FCurve)) {
|
||||
*r_lb = CTX_data_collection_get(C, "selected_editable_fcurves");
|
||||
@@ -921,6 +925,8 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||
else {
|
||||
*r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
|
||||
}
|
||||
/* Account for properties only being available for some sequence types. */
|
||||
ensure_list_items_contain_prop = true;
|
||||
}
|
||||
}
|
||||
return (*r_path != NULL);
|
||||
@@ -929,6 +935,17 @@ bool UI_context_copy_to_selected_list(bContext *C,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ensure_list_items_contain_prop) {
|
||||
const char *prop_id = RNA_property_identifier(prop);
|
||||
LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, r_lb) {
|
||||
if ((ptr->type != link->ptr.type) &&
|
||||
(RNA_struct_type_find_property(link->ptr.type, prop_id) != prop)) {
|
||||
BLI_remlink(r_lb, link);
|
||||
MEM_freeN(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -277,7 +277,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
|
||||
const char *name = data->items.names[data->active];
|
||||
const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
|
||||
|
||||
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen);
|
||||
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
|
||||
|
||||
but->func_arg2 = data->items.pointers[data->active];
|
||||
|
||||
|
@@ -319,7 +319,9 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
|
||||
else {
|
||||
struct NearestVertUserData data = {{0}};
|
||||
const struct NearestVertUserData_Hit *hit = NULL;
|
||||
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT;
|
||||
const eV3DProjTest clip_flag = RV3D_CLIPPING_ENABLED(vc->v3d, vc->rv3d) ?
|
||||
V3D_PROJ_TEST_CLIP_DEFAULT :
|
||||
V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB;
|
||||
BMesh *prev_select_bm = NULL;
|
||||
|
||||
static struct {
|
||||
|
@@ -584,6 +584,11 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static bool voxel_size_edit_poll(bContext *C)
|
||||
{
|
||||
return CTX_wm_region_view3d(C) && object_remesh_poll(C);
|
||||
}
|
||||
|
||||
void OBJECT_OT_voxel_size_edit(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
@@ -592,7 +597,7 @@ void OBJECT_OT_voxel_size_edit(wmOperatorType *ot)
|
||||
ot->idname = "OBJECT_OT_voxel_size_edit";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = object_remesh_poll;
|
||||
ot->poll = voxel_size_edit_poll;
|
||||
ot->invoke = voxel_size_edit_invoke;
|
||||
ot->modal = voxel_size_edit_modal;
|
||||
ot->cancel = voxel_size_edit_cancel;
|
||||
|
@@ -259,8 +259,11 @@ static int sample_detail(bContext *C, int mx, int my, int mode)
|
||||
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
||||
|
||||
Object *ob = vc.obact;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
if (ob == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
SculptSession *ss = ob->sculpt;
|
||||
if (!ss->pbvh) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
@@ -2712,7 +2712,11 @@ static int file_start_filter_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_UI);
|
||||
SpaceFile *sf = CTX_wm_space_file(C);
|
||||
|
||||
ARegion *region_ctx = CTX_wm_region(C);
|
||||
CTX_wm_region_set(C, region);
|
||||
UI_textbutton_activate_rna(C, region, sf->params, "filter_search");
|
||||
CTX_wm_region_set(C, region_ctx);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@@ -111,8 +111,10 @@ void transform_around_single_fallback(TransInfo *t)
|
||||
}
|
||||
if (tc->data_len == 3) {
|
||||
const TransData *td = tc->data;
|
||||
if ((td[0].loc == td[1].loc) && (td[1].loc == td[2].loc)) {
|
||||
is_data_single = true;
|
||||
if ((td[0].flag | td[1].flag | td[2].flag) & TD_BEZTRIPLE) {
|
||||
if ((td[0].loc == td[1].loc) && (td[1].loc == td[2].loc)) {
|
||||
is_data_single = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@@ -317,10 +317,12 @@ void createTransGPencil(bContext *C, TransInfo *t)
|
||||
/* for other transform modes (e.g. shrink-fatten), need to additional data
|
||||
* but never for mirror
|
||||
*/
|
||||
if ((t->mode != TFM_MIRROR) && (is_scale_thickness)) {
|
||||
if (t->mode != TFM_MIRROR) {
|
||||
if (t->mode != TFM_GPENCIL_OPACITY) {
|
||||
td->val = &pt->pressure;
|
||||
td->ival = pt->pressure;
|
||||
if (is_scale_thickness) {
|
||||
td->val = &pt->pressure;
|
||||
td->ival = pt->pressure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
td->val = &pt->strength;
|
||||
|
@@ -595,7 +595,9 @@ bool gimbal_axis(Object *ob, float gmat[3][3])
|
||||
if (pchan->parent) {
|
||||
float parent_mat[3][3];
|
||||
|
||||
copy_m3_m4(parent_mat, pchan->parent->pose_mat);
|
||||
copy_m3_m4(parent_mat,
|
||||
(pchan->bone->flag & BONE_HINGE) ? pchan->parent->bone->arm_mat :
|
||||
pchan->parent->pose_mat);
|
||||
mul_m3_m3m3(mat, parent_mat, tmat);
|
||||
|
||||
/* needed if object transformation isn't identity */
|
||||
|
@@ -49,6 +49,7 @@ bool GPU_mip_render_workaround(void);
|
||||
bool GPU_depth_blitting_workaround(void);
|
||||
bool GPU_unused_fb_slot_workaround(void);
|
||||
bool GPU_context_local_shaders_workaround(void);
|
||||
bool GPU_texture_copy_workaround(void);
|
||||
bool GPU_crappy_amd_driver(void);
|
||||
|
||||
bool GPU_mem_stats_supported(void);
|
||||
|
@@ -96,6 +96,9 @@ static struct GPUGlobal {
|
||||
/* Some crappy Intel drivers don't work well with shaders created in different
|
||||
* rendering contexts. */
|
||||
bool context_local_shaders_workaround;
|
||||
/* Intel drivers exhibit artifacts when using glCopyImageSubData & workbench antialiasing.
|
||||
* (see T76273) */
|
||||
bool texture_copy_workaround;
|
||||
} GG = {1, 0};
|
||||
|
||||
static void gpu_detect_mip_render_workaround(void)
|
||||
@@ -224,6 +227,11 @@ bool GPU_context_local_shaders_workaround(void)
|
||||
return GG.context_local_shaders_workaround;
|
||||
}
|
||||
|
||||
bool GPU_texture_copy_workaround(void)
|
||||
{
|
||||
return GG.texture_copy_workaround;
|
||||
}
|
||||
|
||||
bool GPU_crappy_amd_driver(void)
|
||||
{
|
||||
/* Currently are the same drivers with the `unused_fb_slot` problem. */
|
||||
@@ -287,7 +295,23 @@ void gpu_extensions_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
GG.glew_arb_base_instance_is_supported = GLEW_ARB_base_instance;
|
||||
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) {
|
||||
/* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are
|
||||
* covered since they only support GL 4.4 on windows.
|
||||
* This fixes some issues with workbench antialiasing on Win + Intel GPU. (see T76273) */
|
||||
if (!GLEW_VERSION_4_5) {
|
||||
GG.texture_copy_workaround = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Limit support for GLEW_ARB_base_instance to OpenGL 4.0 and higher. NVIDIA Quadro FX 4800
|
||||
* (TeraScale) report that they support GLEW_ARB_base_instance, but the driver does not support
|
||||
* GLEW_ARB_draw_indirect as it has an OpenGL3 context what also matches the minimum needed
|
||||
* requirements.
|
||||
*
|
||||
* We use it as a target for glMapBuffer(Range) what is part of the OpenGL 4 API. So better
|
||||
* disable it when we don't have an OpenGL4 context (See T77657) */
|
||||
GG.glew_arb_base_instance_is_supported = GLEW_ARB_base_instance && GLEW_VERSION_4_0;
|
||||
GG.glew_arb_texture_cube_map_array_is_supported = GLEW_ARB_texture_cube_map_array;
|
||||
gpu_detect_mip_render_workaround();
|
||||
|
||||
@@ -301,6 +325,7 @@ void gpu_extensions_init(void)
|
||||
GG.mip_render_workaround = true;
|
||||
GG.depth_blitting_workaround = true;
|
||||
GG.unused_fb_slot_workaround = true;
|
||||
GG.texture_copy_workaround = true;
|
||||
GG.context_local_shaders_workaround = GLEW_ARB_get_program_binary;
|
||||
}
|
||||
|
||||
|
@@ -1759,7 +1759,7 @@ void GPU_texture_copy(GPUTexture *dst, GPUTexture *src)
|
||||
BLI_assert(dst->d == 0);
|
||||
BLI_assert(dst->format == src->format);
|
||||
|
||||
if (GLEW_ARB_copy_image) {
|
||||
if (GLEW_ARB_copy_image && !GPU_texture_copy_workaround()) {
|
||||
/* Opengl 4.3 */
|
||||
glCopyImageSubData(src->bindcode,
|
||||
src->target,
|
||||
|
@@ -680,6 +680,15 @@ typedef enum IDRecalcFlag {
|
||||
* input file or for color space changes. */
|
||||
ID_RECALC_SOURCE = (1 << 23),
|
||||
|
||||
/* Virtual recalc tag/marker required for undo in some cases, where actual data does not change
|
||||
* and hence do not require an update, but conceptually we are dealing with something new.
|
||||
*
|
||||
* Current known case: linked IDs made local without requiring any copy. While their users do not
|
||||
* require any update, they have actually been 'virtually' remapped from the linked ID to the
|
||||
* local one.
|
||||
*/
|
||||
ID_RECALC_TAG_FOR_UNDO = (1 << 24),
|
||||
|
||||
/***************************************************************************
|
||||
* Pseudonyms, to have more semantic meaning in the actual code without
|
||||
* using too much low-level and implementation specific tags. */
|
||||
|
@@ -636,12 +636,12 @@ typedef struct UserDef {
|
||||
/** #eUserPref_Flag. */
|
||||
int flag;
|
||||
/** #eDupli_ID_Flags. */
|
||||
short dupflag;
|
||||
unsigned int dupflag;
|
||||
/** #eUserPref_PrefFlag preferences for the preferences. */
|
||||
char pref_flag;
|
||||
char savetime;
|
||||
char mouse_emulate_3_button_modifier;
|
||||
char _pad4[3];
|
||||
char _pad4[1];
|
||||
/** FILE_MAXDIR length. */
|
||||
char tempdir[768];
|
||||
char fontdir[768];
|
||||
|
@@ -759,6 +759,10 @@ static void lib_relocate_do(Main *bmain,
|
||||
BLI_addtail(which_libbase(bmain, GS(old_id->name)), old_id);
|
||||
}
|
||||
|
||||
/* Since our (old) reloaded IDs were removed from main, the user count done for them in linking
|
||||
* code is wrong, we need to redo it here after adding them back to main. */
|
||||
BKE_main_id_refcount_recompute(bmain, false);
|
||||
|
||||
/* Note that in reload case, we also want to replace indirect usages. */
|
||||
const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE |
|
||||
ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE |
|
||||
|
@@ -247,8 +247,12 @@ int main(int argc,
|
||||
|
||||
/* Unbuffered stdout makes stdout and stderr better synchronized, and helps
|
||||
* when stepping through code in a debugger (prints are immediately
|
||||
* visible). */
|
||||
* visible). However disabling buffering causes lock contention on windows
|
||||
* see T76767 for detais, since this is a debugging aid, we do not enable
|
||||
* the unbuffered behavior for release builds. */
|
||||
#ifndef NDEBUG
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/* We delay loading of openmp so we can set the policy here. */
|
||||
|
Reference in New Issue
Block a user