Code refactor: use shader pointers rather than shader indexes.

This commit is contained in:
Brecht Van Lommel 2016-05-14 14:50:03 +02:00
parent 08670d3b81
commit 0e8cd14dfe
20 changed files with 109 additions and 118 deletions

View File

@ -52,7 +52,7 @@ struct XMLReadState {
Scene *scene; /* scene pointer */
Transform tfm; /* current transform state */
bool smooth; /* smooth normal state */
int shader; /* current shader */
Shader *shader; /* current shader */
string base; /* base path to current file*/
float dicing_rate; /* current dicing rate */
Mesh::DisplacementMethod displacement_method;
@ -60,7 +60,7 @@ struct XMLReadState {
XMLReadState()
: scene(NULL),
smooth(false),
shader(0),
shader(NULL),
dicing_rate(0.0f),
displacement_method(Mesh::DISPLACE_BUMP)
{
@ -865,7 +865,7 @@ static void xml_read_background(const XMLReadState& state, pugi::xml_node node)
xml_read_bool(&bg->transparent, node, "transparent");
/* Background Shader */
Shader *shader = state.scene->shaders[state.scene->default_background];
Shader *shader = state.scene->default_background;
xml_read_bool(&shader->heterogeneous_volume, node, "heterogeneous_volume");
xml_read_int(&shader->volume_interpolation_method, node, "volume_interpolation_method");
@ -904,7 +904,7 @@ static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
mesh->used_shaders.push_back(state.shader);
/* read state */
int shader = state.shader;
int shader = 0;
bool smooth = state.smooth;
mesh->displacement_method = state.displacement_method;
@ -1064,7 +1064,7 @@ static void xml_read_patch(const XMLReadState& state, pugi::xml_node node)
mesh->used_shaders.push_back(state.shader);
/* split */
SubdParams sdparams(mesh, state.shader, state.smooth);
SubdParams sdparams(mesh, 0, state.smooth);
xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
DiagSplit dsplit(sdparams);
@ -1161,17 +1161,14 @@ static void xml_read_state(XMLReadState& state, pugi::xml_node node)
string shadername;
if(xml_read_string(&shadername, node, "shader")) {
int i = 0;
bool found = false;
foreach(Shader *shader, state.scene->shaders) {
if(shader->name == shadername) {
state.shader = i;
state.shader = shader;
found = true;
break;
}
i++;
}
if(!found)

View File

@ -138,8 +138,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
int mi = clamp(b_part.material()-1, 0, mesh->used_shaders.size()-1);
int shader = mesh->used_shaders[mi];
int shader = clamp(b_part.material()-1, 0, mesh->used_shaders.size()-1);
int draw_step = background ? b_part.render_step() : b_part.draw_step();
int totparts = b_psys.particles.length();
int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);

View File

@ -532,7 +532,7 @@ static void attr_create_pointiness(Scene *scene,
static void create_mesh(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
const vector<uint>& used_shaders)
const vector<Shader*>& used_shaders)
{
/* count vertices and faces */
int numverts = b_mesh.vertices.length();
@ -588,8 +588,7 @@ static void create_mesh(Scene *scene,
for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) {
int4 vi = get_int4(f->vertices_raw());
int n = (vi[3] == 0)? 3: 4;
int mi = clamp(f->material_index(), 0, used_shaders.size()-1);
int shader = used_shaders[mi];
int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
bool smooth = f->use_smooth() || use_loop_normals;
/* split vertices if normal is different
@ -660,14 +659,14 @@ static void create_subd_mesh(Scene *scene,
BL::Object& b_ob,
BL::Mesh& b_mesh,
PointerRNA *cmesh,
const vector<uint>& used_shaders,
const vector<Shader*>& used_shaders,
float dicing_rate,
int max_subdivisions)
{
Mesh basemesh;
create_mesh(scene, &basemesh, b_mesh, used_shaders);
SubdParams sdparams(mesh, used_shaders[0], true, false);
SubdParams sdparams(mesh, 0, true, false);
sdparams.dicing_rate = max(0.1f, RNA_float_get(cmesh, "dicing_rate") * dicing_rate);
sdparams.max_level = max_subdivisions;
@ -700,7 +699,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
BL::Material material_override = render_layer.material_override;
/* find shader indices */
vector<uint> used_shaders;
vector<Shader*> used_shaders;
BL::Object::material_slots_iterator slot;
for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
@ -742,8 +741,8 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
* because the shader needs different mesh attributes */
bool attribute_recalc = false;
foreach(uint shader, mesh->used_shaders)
if(scene->shaders[shader]->need_update_attributes)
foreach(Shader *shader, mesh->used_shaders)
if(shader->need_update_attributes)
attribute_recalc = true;
if(!attribute_recalc)

View File

@ -155,13 +155,8 @@ void BlenderSync::sync_light(BL::Object& b_parent,
light->dir = -transform_get_column(&tfm, 2);
/* shader */
vector<uint> used_shaders;
vector<Shader*> used_shaders;
find_shader(b_lamp, used_shaders, scene->default_light);
if(used_shaders.size() == 0)
used_shaders.push_back(scene->default_light);
light->shader = used_shaders[0];
/* shadow */

View File

@ -37,18 +37,13 @@ typedef map<std::string, ConvertNode*> ProxyMap;
/* Find */
void BlenderSync::find_shader(BL::ID& id,
vector<uint>& used_shaders,
int default_shader)
vector<Shader*>& used_shaders,
Shader *default_shader)
{
Shader *shader = (id)? shader_map.find(id): scene->shaders[default_shader];
Shader *shader = (id)? shader_map.find(id): default_shader;
for(size_t i = 0; i < scene->shaders.size(); i++) {
if(scene->shaders[i] == shader) {
used_shaders.push_back(i);
scene->shaders[i]->tag_used(scene);
break;
}
}
used_shaders.push_back(shader);
shader->tag_used(scene);
}
/* RNA translation utilities */
@ -1207,7 +1202,7 @@ static void add_nodes(Scene *scene,
void BlenderSync::sync_materials(bool update_all)
{
shader_map.set_default(scene->shaders[scene->default_surface]);
shader_map.set_default(scene->default_surface);
/* material loop */
BL::BlendData::materials_iterator b_mat;
@ -1262,7 +1257,7 @@ void BlenderSync::sync_world(bool update_all)
BL::World b_world = b_scene.world();
if(world_recalc || update_all || b_world.ptr.data != world_map) {
Shader *shader = scene->shaders[scene->default_background];
Shader *shader = scene->default_background;
ShaderGraph *graph = new ShaderGraph();
/* create nodes */
@ -1342,7 +1337,7 @@ void BlenderSync::sync_world(bool update_all)
void BlenderSync::sync_lamps(bool update_all)
{
shader_map.set_default(scene->shaders[scene->default_light]);
shader_map.set_default(scene->default_light);
/* lamp loop */
BL::BlendData::lamps_iterator b_lamp;

View File

@ -175,8 +175,8 @@ bool BlenderSync::sync_recalc()
world_recalc = true;
}
else if(b_world->node_tree() && b_world->use_nodes()) {
Shader *shader = scene->shaders[scene->default_background];
if(has_updated_objects && shader != NULL && shader->has_object_dependency) {
Shader *shader = scene->default_background;
if(has_updated_objects && shader->has_object_dependency) {
world_recalc = true;
}
}

View File

@ -146,7 +146,7 @@ private:
void sync_images();
/* util */
void find_shader(BL::ID& id, vector<uint>& used_shaders, int default_shader);
void find_shader(BL::ID& id, vector<Shader*>& used_shaders, Shader *default_shader);
bool BKE_object_is_modified(BL::Object& b_ob);
bool object_is_mesh(BL::Object& b_ob);
bool object_is_light(BL::Object& b_ob);

View File

@ -37,7 +37,7 @@ Background::Background()
use_ao = false;
visibility = PATH_RAY_ALL_VISIBILITY;
shader = 0;
shader = NULL;
transparent = false;
need_update = true;
@ -54,10 +54,14 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
device_free(device, dscene);
if(use_shader)
shader = scene->default_background;
Shader *bg_shader = shader;
if(use_shader) {
if(!bg_shader)
bg_shader = scene->default_background;
}
else
shader = scene->default_empty;
bg_shader = scene->default_empty;
/* set shader index and transparent option */
KernelBackground *kbackground = &dscene->data.background;
@ -72,15 +76,15 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
}
kbackground->transparent = transparent;
kbackground->surface_shader = scene->shader_manager->get_shader_id(shader);
kbackground->surface_shader = scene->shader_manager->get_shader_id(bg_shader);
if(scene->shaders[shader]->has_volume)
if(bg_shader->has_volume)
kbackground->volume_shader = kbackground->surface_shader;
else
kbackground->volume_shader = SHADER_NONE;
/* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */
if(scene->shaders[shader]->graph->nodes.size() <= 1) {
if(bg_shader->graph->nodes.size() <= 1) {
kbackground->surface_shader |= SHADER_EXCLUDE_ANY;
}
/* Background present, check visibilities */

View File

@ -23,6 +23,7 @@ CCL_NAMESPACE_BEGIN
class Device;
class DeviceScene;
class Shader;
class Scene;
class Background {
@ -34,7 +35,7 @@ public:
bool use_ao;
uint visibility;
uint shader;
Shader *shader;
bool transparent;
bool need_update;

View File

@ -126,7 +126,7 @@ Light::Light()
use_transmission = true;
use_scatter = true;
shader = 0;
shader = NULL;
samples = 1;
max_bounces = 1024;
@ -147,7 +147,7 @@ bool Light::has_contribution(Scene *scene)
if(type == LIGHT_BACKGROUND) {
return true;
}
return scene->shaders[shader]->has_surface_emission;
return (shader) ? shader->has_surface_emission : scene->default_light->has_surface_emission;
}
/* Light Manager */
@ -180,7 +180,7 @@ void LightManager::disable_ineffective_light(Device *device, Scene *scene)
* - If unsupported on a device
* - If we don't need it (no HDRs etc.)
*/
Shader *shader = scene->shaders[scene->background->shader];
Shader *shader = (scene->background->shader) ? scene->background->shader : scene->default_background;
bool disable_mis = !(has_portal || shader->has_surface_spatial_varying) ||
!(device->info.advanced_shading);
if(disable_mis) {
@ -223,9 +223,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
continue;
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
foreach(Shader *shader, mesh->used_shaders) {
if(shader->use_mis && shader->has_surface_emission) {
have_emission = true;
break;
@ -270,9 +268,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
}
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
foreach(Shader *shader, mesh->used_shaders) {
if(shader->use_mis && shader->has_surface_emission) {
have_emission = true;
break;
@ -604,7 +600,8 @@ void LightManager::device_update_points(Device *device,
}
float3 co = light->co;
int shader_id = scene->shader_manager->get_shader_id(light->shader);
Shader *shader = (light->shader) ? light->shader : scene->default_light;
int shader_id = scene->shader_manager->get_shader_id(shader);
float samples = __int_as_float(light->samples);
float max_bounces = __int_as_float(light->max_bounces);

View File

@ -27,6 +27,7 @@ CCL_NAMESPACE_BEGIN
class Device;
class DeviceScene;
class Progress;
class Shader;
class Scene;
class Light {
@ -59,7 +60,7 @@ public:
bool is_portal;
bool is_enabled;
int shader;
Shader *shader;
int samples;
int max_bounces;

View File

@ -413,7 +413,9 @@ void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal)
if(shader_ptr[i] != last_shader || last_smooth != smooth[i]) {
last_shader = shader_ptr[i];
last_smooth = smooth[i];
shader_id = scene->shader_manager->get_shader_id(last_shader, this, last_smooth);
Shader *shader = (last_shader < used_shaders.size()) ?
used_shaders[last_shader] : scene->default_surface;
shader_id = scene->shader_manager->get_shader_id(shader, this, last_smooth);
}
tri_shader[i] = shader_id;
@ -483,7 +485,9 @@ void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, s
for(size_t i = 0; i < curve_num; i++) {
Curve curve = curve_ptr[i];
shader_id = scene->shader_manager->get_shader_id(curve.shader, this, false);
Shader *shader = (curve.shader < used_shaders.size()) ?
used_shaders[curve.shader] : scene->default_surface;
shader_id = scene->shader_manager->get_shader_id(shader, this, false);
curve_data[i] = make_float4(
__int_as_float(curve.first_key + curvekey_offset),
@ -545,8 +549,8 @@ void Mesh::tag_update(Scene *scene, bool rebuild)
scene->light_manager->need_update = true;
}
else {
foreach(uint sindex, used_shaders)
if(scene->shaders[sindex]->has_surface_emission)
foreach(Shader *shader, used_shaders)
if(shader->has_surface_emission)
scene->light_manager->need_update = true;
}
@ -921,8 +925,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
scene->need_global_attributes(mesh_attributes[i]);
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
foreach(Shader *shader, mesh->used_shaders) {
mesh_attributes[i].add(shader->attributes);
}
}
@ -1168,8 +1171,7 @@ void MeshManager::device_update_flags(Device * /*device*/,
/* update flags */
foreach(Mesh *mesh, scene->meshes) {
mesh->has_volume = false;
foreach(uint shader_index, mesh->used_shaders) {
const Shader *shader = scene->shaders[shader_index];
foreach(const Shader *shader, mesh->used_shaders) {
if(shader->has_volume) {
mesh->has_volume = true;
}
@ -1192,8 +1194,7 @@ void MeshManager::device_update_displacement_images(Device *device,
set<int> bump_images;
foreach(Mesh *mesh, scene->meshes) {
if(mesh->need_update) {
foreach(uint shader_index, mesh->used_shaders) {
Shader *shader = scene->shaders[shader_index];
foreach(Shader *shader, mesh->used_shaders) {
if(shader->graph_bump == NULL) {
continue;
}
@ -1239,8 +1240,8 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
/* update normals */
foreach(Mesh *mesh, scene->meshes) {
foreach(uint shader, mesh->used_shaders) {
if(scene->shaders[shader]->need_update_attributes)
foreach(Shader *shader, mesh->used_shaders) {
if(shader->need_update_attributes)
mesh->need_update = true;
}
@ -1428,8 +1429,8 @@ bool Mesh::need_attribute(Scene *scene, AttributeStandard std)
if(scene->need_global_attribute(std))
return true;
foreach(uint shader, used_shaders)
if(scene->shaders[shader]->attributes.find(std))
foreach(Shader *shader, used_shaders)
if(shader->attributes.find(std))
return true;
return false;
@ -1440,8 +1441,8 @@ bool Mesh::need_attribute(Scene *scene, ustring name)
if(name == ustring())
return false;
foreach(uint shader, used_shaders)
if(scene->shaders[shader]->attributes.find(name))
foreach(Shader *shader, used_shaders)
if(shader->attributes.find(name))
return true;
return false;

View File

@ -94,7 +94,7 @@ public:
vector<float4> curve_keys; /* co + radius */
vector<Curve> curves;
vector<uint> used_shaders;
vector<Shader*> used_shaders;
AttributeSet attributes;
AttributeSet curve_attributes;

View File

@ -32,8 +32,8 @@ bool MeshManager::displace(Device *device, DeviceScene *dscene, Scene *scene, Me
bool has_displacement = false;
if(mesh->displacement_method != Mesh::DISPLACE_BUMP) {
foreach(uint sindex, mesh->used_shaders)
if(scene->shaders[sindex]->has_displacement)
foreach(Shader *shader, mesh->used_shaders)
if(shader->has_displacement)
has_displacement = true;
}

View File

@ -185,9 +185,7 @@ void Object::tag_update(Scene *scene)
if(mesh->transform_applied)
mesh->need_update = true;
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
foreach(Shader *shader, mesh->used_shaders) {
if(shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
}

View File

@ -99,7 +99,7 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
thread_scoped_lock lock(ss_mutex);
OSLCompiler compiler((void*)this, (void*)ss, scene->image_manager);
compiler.background = (shader == scene->shaders[scene->default_background]);
compiler.background = (shader == scene->default_background);
compiler.compile(scene, og, shader);
if(shader->use_mis && shader->has_surface_emission)

View File

@ -183,10 +183,10 @@ public:
BakeManager *bake_manager;
/* default shaders */
int default_surface;
int default_light;
int default_background;
int default_empty;
Shader *default_surface;
Shader *default_light;
Shader *default_background;
Shader *default_empty;
/* device */
Device *device;

View File

@ -157,6 +157,7 @@ Shader::Shader()
has_object_dependency = false;
has_integrator_dependency = false;
id = -1;
used = false;
need_update = true;
@ -287,10 +288,10 @@ uint ShaderManager::get_attribute_id(AttributeStandard std)
return (uint)std;
}
int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth)
int ShaderManager::get_shader_id(Shader *shader, Mesh *mesh, bool smooth)
{
/* get a shader id to pass to the kernel */
int id = shader*2;
int id = shader->id*2;
/* index depends bump since this setting is not in the shader */
if(mesh && mesh->displacement_method != Mesh::DISPLACE_TRUE)
@ -309,21 +310,27 @@ void ShaderManager::device_update_shaders_used(Scene *scene)
{
/* figure out which shaders are in use, so SVM/OSL can skip compiling them
* for speed and avoid loading image textures into memory */
foreach(Shader *shader, scene->shaders)
uint id = 0;
foreach(Shader *shader, scene->shaders) {
shader->used = false;
shader->id = id++;
}
scene->shaders[scene->background->shader]->used = true;
scene->shaders[scene->default_surface]->used = true;
scene->shaders[scene->default_light]->used = true;
scene->shaders[scene->default_background]->used = true;
scene->shaders[scene->default_empty]->used = true;
scene->default_surface->used = true;
scene->default_light->used = true;
scene->default_background->used = true;
scene->default_empty->used = true;
if(scene->background->shader)
scene->background->shader->used = true;
foreach(Mesh *mesh, scene->meshes)
foreach(uint shader, mesh->used_shaders)
scene->shaders[shader]->used = true;
foreach(Shader *shader, mesh->used_shaders)
shader->used = true;
foreach(Light *light, scene->lights)
scene->shaders[light->shader]->used = true;
if(light->shader)
light->shader->used = true;
}
void ShaderManager::device_update_common(Device *device,
@ -426,13 +433,11 @@ void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scen
void ShaderManager::add_default(Scene *scene)
{
Shader *shader;
ShaderGraph *graph;
ShaderNode *closure, *out;
/* default surface */
{
graph = new ShaderGraph();
ShaderGraph *graph = new ShaderGraph();
closure = graph->add(new DiffuseBsdfNode());
closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
@ -440,16 +445,16 @@ void ShaderManager::add_default(Scene *scene)
graph->connect(closure->output("BSDF"), out->input("Surface"));
shader = new Shader();
Shader *shader = new Shader();
shader->name = "default_surface";
shader->graph = graph;
scene->shaders.push_back(shader);
scene->default_surface = scene->shaders.size() - 1;
scene->default_surface = shader;
}
/* default light */
{
graph = new ShaderGraph();
ShaderGraph *graph = new ShaderGraph();
closure = graph->add(new EmissionNode());
closure->input("Color")->value = make_float3(0.8f, 0.8f, 0.8f);
@ -458,33 +463,33 @@ void ShaderManager::add_default(Scene *scene)
graph->connect(closure->output("Emission"), out->input("Surface"));
shader = new Shader();
Shader *shader = new Shader();
shader->name = "default_light";
shader->graph = graph;
scene->shaders.push_back(shader);
scene->default_light = scene->shaders.size() - 1;
scene->default_light = shader;
}
/* default background */
{
graph = new ShaderGraph();
ShaderGraph *graph = new ShaderGraph();
shader = new Shader();
Shader *shader = new Shader();
shader->name = "default_background";
shader->graph = graph;
scene->shaders.push_back(shader);
scene->default_background = scene->shaders.size() - 1;
scene->default_background = shader;
}
/* default empty */
{
graph = new ShaderGraph();
ShaderGraph *graph = new ShaderGraph();
shader = new Shader();
Shader *shader = new Shader();
shader->name = "default_empty";
shader->graph = graph;
scene->shaders.push_back(shader);
scene->default_empty = scene->shaders.size() - 1;
scene->default_empty = shader;
}
}

View File

@ -112,6 +112,7 @@ public:
AttributeRequestSet attributes;
/* determined before compiling */
uint id;
bool used;
#ifdef WITH_OSL
@ -159,7 +160,7 @@ public:
uint get_attribute_id(AttributeStandard std);
/* get shader id for mesh faces */
int get_shader_id(uint shader, Mesh *mesh = NULL, bool smooth = false);
int get_shader_id(Shader *shader, Mesh *mesh = NULL, bool smooth = false);
/* add default shaders to scene, to use as default for things that don't
* have any shader assigned explicitly */

View File

@ -66,9 +66,7 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
}
for(i = 0; i < scene->shaders.size(); i++) {
Shader *shader = scene->shaders[i];
foreach(Shader *shader, scene->shaders) {
if(progress.get_cancel()) return;
assert(shader->graph);
@ -78,8 +76,8 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
SVMCompiler::Summary summary;
SVMCompiler compiler(scene->shader_manager, scene->image_manager);
compiler.background = ((int)i == scene->default_background);
compiler.compile(scene, shader, svm_nodes, i, &summary);
compiler.background = (shader == scene->default_background);
compiler.compile(scene, shader, svm_nodes, shader->id, &summary);
VLOG(2) << "Compilation summary:\n"
<< "Shader name: " << shader->name << "\n"