Cycles: Revert all host update specific changes

The approach didn't turn out to be that useful after all as there
are unavoidable dependencies of data from the device. For example,
to know whether object intersects volume or not it is required to
run displacement kernels.

The way of splitting host and device updates caused state where
some data is not yet available, causing confusion and leaving
code to be error-prone.
This commit is contained in:
Sergey Sharybin 2021-10-21 14:52:34 +02:00
parent b714f9bf43
commit 8733d310e5
8 changed files with 75 additions and 147 deletions

View File

@ -91,51 +91,70 @@ void OSLShaderManager::reset(Scene * /*scene*/)
shading_system_init();
}
void OSLShaderManager::host_update_specific(Scene *scene, Progress &progress)
void OSLShaderManager::device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
{
if (!need_update()) {
if (!need_update())
return;
}
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->osl.times.add_entry({"host_update", time});
scene->update_stats->osl.times.add_entry({"device_update", time});
}
});
VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
device_free(device, dscene, scene);
/* set texture system */
scene->image_manager->set_osl_texture_system((void *)ts);
/* create shaders */
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
Shader *background_shader = scene->background->get_shader(scene);
for (Shader *shader : scene->shaders) {
foreach (Shader *shader, scene->shaders) {
assert(shader->graph);
if (progress.get_cancel()) {
if (progress.get_cancel())
return;
}
/* we can only compile one shader at the time as the OSL ShadingSystem
/* we can only compile one shader at the time as the OSL ShadingSytem
* has a single state, but we put the lock here so different renders can
* compile shaders alternating */
thread_scoped_lock lock(ss_mutex);
OSLCompiler compiler(this, services, ss, scene);
compiler.background = (shader == background_shader);
compiler.compile(shader);
compiler.compile(og, shader);
if (shader->get_use_mis() && shader->has_surface_emission) {
if (shader->get_use_mis() && shader->has_surface_emission)
scene->light_manager->tag_update(scene, LightManager::SHADER_COMPILED);
}
}
/* setup shader engine */
og->ss = ss;
og->ts = ts;
og->services = services;
int background_id = scene->shader_manager->get_shader_id(background_shader);
og->background_state = og->surface_state[background_id & SHADER_MASK];
og->use = true;
foreach (Shader *shader, scene->shaders)
shader->clear_modified();
update_flags = UPDATE_NONE;
/* add special builtin texture types */
services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
services->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL));
device_update_common(device, dscene, scene, progress);
{
/* Perform greedyjit optimization.
*
@ -153,51 +172,6 @@ void OSLShaderManager::host_update_specific(Scene *scene, Progress &progress)
}
}
void OSLShaderManager::device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
{
if (!need_update())
return;
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->osl.times.add_entry({"device_update", time});
}
});
device_free(device, dscene, scene);
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
Shader *background_shader = scene->background->get_shader(scene);
/* Setup shader engine. */
og->ss = ss;
og->ts = ts;
og->services = services;
for (Shader *shader : scene->shaders) {
/* push state to array for lookup */
og->surface_state.push_back(shader->osl_surface_ref);
og->volume_state.push_back(shader->osl_volume_ref);
og->displacement_state.push_back(shader->osl_displacement_ref);
og->bump_state.push_back(shader->osl_surface_bump_ref);
shader->clear_modified();
}
const int background_id = scene->shader_manager->get_shader_id(background_shader);
const int background_state_index = (background_id & SHADER_MASK);
DCHECK_LT(background_state_index, og->surface_state.size());
og->background_state = og->surface_state[background_state_index];
og->use = true;
update_flags = UPDATE_NONE;
device_update_common(device, dscene, scene, progress);
}
void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
{
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
@ -1158,7 +1132,7 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph
return group;
}
void OSLCompiler::compile(Shader *shader)
void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
{
if (shader->is_modified()) {
ShaderGraph *graph = shader->graph;
@ -1220,6 +1194,12 @@ void OSLCompiler::compile(Shader *shader)
else
shader->osl_displacement_ref = OSL::ShaderGroupRef();
}
/* push state to array for lookup */
og->surface_state.push_back(shader->osl_surface_ref);
og->volume_state.push_back(shader->osl_volume_ref);
og->displacement_state.push_back(shader->osl_displacement_ref);
og->bump_state.push_back(shader->osl_surface_bump_ref);
}
void OSLCompiler::parameter_texture(const char *name, ustring filename, ustring colorspace)

View File

@ -79,8 +79,6 @@ class OSLShaderManager : public ShaderManager {
return true;
}
void host_update_specific(Scene *scene, Progress &progress) override;
void device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
@ -140,7 +138,7 @@ class OSLCompiler {
OSL::ShadingSystem *shadingsys,
Scene *scene);
#endif
void compile(Shader *shader);
void compile(OSLGlobals *og, Shader *shader);
void add(ShaderNode *node, const char *name, bool isfilepath = false);

View File

@ -228,22 +228,6 @@ void Scene::free_memory(bool final)
}
}
void Scene::host_update(Progress &progress)
{
if (update_stats) {
update_stats->clear();
}
scoped_callback_timer timer([this](double time) {
if (update_stats) {
update_stats->scene.times.add_entry({"host_update", time});
}
});
progress.set_status("Updating Shaders");
shader_manager->host_update(this, progress);
}
void Scene::device_update(Device *device_, Progress &progress)
{
if (!device)
@ -251,6 +235,10 @@ void Scene::device_update(Device *device_, Progress &progress)
bool print_stats = need_data_update();
if (update_stats) {
update_stats->clear();
}
scoped_callback_timer timer([this, print_stats](double time) {
if (update_stats) {
update_stats->scene.times.add_entry({"device_update", time});
@ -549,17 +537,11 @@ bool Scene::update(Progress &progress)
return false;
}
/* Update scene data on the host side.
* Only updates which do not depend on the kernel (including kernel features). */
progress.set_status("Updating Scene");
MEM_GUARDED_CALL(&progress, host_update, progress);
/* Load render kernels. After host scene update so that the required kernel features are known.
*/
/* Load render kernels, before device update where we upload data to the GPU. */
load_kernels(progress, false);
/* Upload scene data to the device. */
progress.set_status("Updating Scene Device");
/* Upload scene data to the GPU. */
progress.set_status("Updating Scene");
MEM_GUARDED_CALL(&progress, device_update, device, progress);
return true;

View File

@ -251,8 +251,6 @@ class Scene : public NodeOwner {
Scene(const SceneParams &params, Device *device);
~Scene();
void host_update(Progress &progress);
void device_update(Device *device, Progress &progress);
bool need_global_attribute(AttributeStandard std);

View File

@ -462,7 +462,10 @@ int ShaderManager::get_shader_id(Shader *shader, bool smooth)
return id;
}
void ShaderManager::host_update(Scene *scene, Progress &progress)
void ShaderManager::device_update(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
{
if (!need_update()) {
return;
@ -480,18 +483,6 @@ void ShaderManager::host_update(Scene *scene, Progress &progress)
assert(scene->default_background->reference_count() != 0);
assert(scene->default_empty->reference_count() != 0);
host_update_specific(scene, progress);
}
void ShaderManager::device_update(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress)
{
if (!need_update()) {
return;
}
device_update_specific(device, dscene, scene, progress);
}

View File

@ -193,9 +193,6 @@ class ShaderManager {
return false;
}
void host_update(Scene *scene, Progress &progress);
virtual void host_update_specific(Scene *scene, Progress &progress) = 0;
/* device update */
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
virtual void device_update_specific(Device *device,

View File

@ -47,10 +47,10 @@ void SVMShaderManager::reset(Scene * /*scene*/)
{
}
static void host_compile_shader(Scene *scene,
Shader *shader,
Progress *progress,
array<int4> *svm_nodes)
void SVMShaderManager::device_update_shader(Scene *scene,
Shader *shader,
Progress *progress,
array<int4> *svm_nodes)
{
if (progress->get_cancel()) {
return;
@ -69,32 +69,6 @@ static void host_compile_shader(Scene *scene,
<< summary.full_report();
}
void SVMShaderManager::host_update_specific(Scene *scene, Progress &progress)
{
if (!need_update()) {
return;
}
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->svm.times.add_entry({"host_update", time});
}
});
const int num_shaders = scene->shaders.size();
VLOG(1) << "Total " << num_shaders << " shaders.";
/* Build all shaders. */
TaskPool task_pool;
shader_svm_nodes_.resize(num_shaders);
for (int i = 0; i < num_shaders; i++) {
task_pool.push(function_bind(
host_compile_shader, scene, scene->shaders[i], &progress, &shader_svm_nodes_[i]));
}
task_pool.wait_work();
}
void SVMShaderManager::device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
@ -118,6 +92,19 @@ void SVMShaderManager::device_update_specific(Device *device,
/* test if we need to update */
device_free(device, dscene, scene);
/* Build all shaders. */
TaskPool task_pool;
vector<array<int4>> shader_svm_nodes(num_shaders);
for (int i = 0; i < num_shaders; i++) {
task_pool.push(function_bind(&SVMShaderManager::device_update_shader,
this,
scene,
scene->shaders[i],
&progress,
&shader_svm_nodes[i]));
}
task_pool.wait_work();
if (progress.get_cancel()) {
return;
}
@ -127,7 +114,7 @@ void SVMShaderManager::device_update_specific(Device *device,
int svm_nodes_size = num_shaders;
for (int i = 0; i < num_shaders; i++) {
/* Since we're not copying the local jump node, the size ends up being one node lower. */
svm_nodes_size += shader_svm_nodes_[i].size() - 1;
svm_nodes_size += shader_svm_nodes[i].size() - 1;
}
int4 *svm_nodes = dscene->svm_nodes.alloc(svm_nodes_size);
@ -145,22 +132,22 @@ void SVMShaderManager::device_update_specific(Device *device,
* Each compiled shader starts with a jump node that has offsets local
* to the shader, so copy those and add the offset into the global node list. */
int4 &global_jump_node = svm_nodes[shader->id];
int4 &local_jump_node = shader_svm_nodes_[i][0];
int4 &local_jump_node = shader_svm_nodes[i][0];
global_jump_node.x = NODE_SHADER_JUMP;
global_jump_node.y = local_jump_node.y - 1 + node_offset;
global_jump_node.z = local_jump_node.z - 1 + node_offset;
global_jump_node.w = local_jump_node.w - 1 + node_offset;
node_offset += shader_svm_nodes_[i].size() - 1;
node_offset += shader_svm_nodes[i].size() - 1;
}
/* Copy the nodes of each shader into the correct location. */
svm_nodes += num_shaders;
for (int i = 0; i < num_shaders; i++) {
int shader_size = shader_svm_nodes_[i].size() - 1;
int shader_size = shader_svm_nodes[i].size() - 1;
memcpy(svm_nodes, &shader_svm_nodes_[i][1], sizeof(int4) * shader_size);
memcpy(svm_nodes, &shader_svm_nodes[i][1], sizeof(int4) * shader_size);
svm_nodes += shader_size;
}
@ -174,8 +161,6 @@ void SVMShaderManager::device_update_specific(Device *device,
update_flags = UPDATE_NONE;
shader_svm_nodes_.clear();
VLOG(1) << "Shader manager updated " << num_shaders << " shaders in " << time_dt() - start_time
<< " seconds.";
}

View File

@ -46,8 +46,6 @@ class SVMShaderManager : public ShaderManager {
void reset(Scene *scene) override;
void host_update_specific(Scene *scene, Progress &progress) override;
void device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
@ -55,11 +53,10 @@ class SVMShaderManager : public ShaderManager {
void device_free(Device *device, DeviceScene *dscene, Scene *scene) override;
protected:
/* Compiled shader nodes.
*
* The compilation happens in the `host_update_specific()`, and the `device_update_specific()`
* moves these nodes to the device. */
vector<array<int4>> shader_svm_nodes_;
void device_update_shader(Scene *scene,
Shader *shader,
Progress *progress,
array<int4> *svm_nodes);
};
/* Graph Compiler */