Cleanup: add ImageHandle to centralize image ownership logic
This commit is contained in:
committed by
Brecht Van Lommel
parent
ec3eeee46b
commit
d8aa613d94
@@ -686,14 +686,6 @@ static ShaderNode *add_node(Scene *scene,
|
||||
for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) {
|
||||
image->tiles.push_back(b_iter->number());
|
||||
}
|
||||
|
||||
/* TODO: restore */
|
||||
/* TODO(sergey): Does not work properly when we change builtin type. */
|
||||
#if 0
|
||||
if (b_image.is_updated()) {
|
||||
scene->image_manager->tag_reload_image(image->image_key());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
node = image;
|
||||
}
|
||||
@@ -730,14 +722,6 @@ static ShaderNode *add_node(Scene *scene,
|
||||
|
||||
env->animated = b_env_node.image_user().use_auto_refresh();
|
||||
env->alpha_type = get_image_alpha_type(b_image);
|
||||
|
||||
/* TODO: restore */
|
||||
/* TODO(sergey): Does not work properly when we change builtin type. */
|
||||
#if 0
|
||||
if (b_image.is_updated()) {
|
||||
scene->image_manager->tag_reload_image(env->image_key());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
node = env;
|
||||
}
|
||||
@@ -885,14 +869,9 @@ static ShaderNode *add_node(Scene *scene,
|
||||
point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
|
||||
point_density->interpolation = get_image_interpolation(b_point_density_node);
|
||||
point_density->builtin_data = b_point_density_node.ptr.data;
|
||||
point_density->image_manager = scene->image_manager;
|
||||
|
||||
/* TODO(sergey): Use more proper update flag. */
|
||||
if (true) {
|
||||
point_density->add_image();
|
||||
b_point_density_node.cache_point_density(b_depsgraph);
|
||||
scene->image_manager->tag_reload_image(point_density->image_key());
|
||||
}
|
||||
point_density->add_image(scene->image_manager);
|
||||
b_point_density_node.cache_point_density(b_depsgraph);
|
||||
node = point_density;
|
||||
|
||||
/* Transformation form world space to texture space.
|
||||
|
||||
@@ -48,15 +48,12 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
|
||||
mesh->volume_isovalue = b_domain.clipping();
|
||||
|
||||
Attribute *attr = mesh->attributes.add(std);
|
||||
VoxelAttribute *volume_data = attr->data_voxel();
|
||||
ImageMetaData metadata;
|
||||
|
||||
ImageKey key;
|
||||
key.filename = Attribute::standard_name(std);
|
||||
key.builtin_data = b_ob.ptr.data;
|
||||
|
||||
volume_data->manager = image_manager;
|
||||
volume_data->slot = image_manager->add_image(key, frame, metadata);
|
||||
attr->add(image_manager->add_image(key, frame));
|
||||
}
|
||||
|
||||
/* Create a matrix to transform from object space to mesh texture space.
|
||||
|
||||
@@ -28,13 +28,10 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
Attribute::~Attribute()
|
||||
{
|
||||
/* for voxel data, we need to remove the image from the image manager */
|
||||
/* For voxel data, we need to free the image handle. */
|
||||
if (element == ATTR_ELEMENT_VOXEL) {
|
||||
VoxelAttribute *voxel_data = data_voxel();
|
||||
|
||||
if (voxel_data && voxel_data->slot != -1) {
|
||||
voxel_data->manager->remove_image(voxel_data->slot);
|
||||
}
|
||||
ImageHandle &handle = data_voxel();
|
||||
handle.~ImageHandle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,15 +120,13 @@ void Attribute::add(const Transform &f)
|
||||
buffer.push_back(data[i]);
|
||||
}
|
||||
|
||||
void Attribute::add(const VoxelAttribute &f)
|
||||
void Attribute::add(const ImageHandle &handle)
|
||||
{
|
||||
assert(data_sizeof() == sizeof(VoxelAttribute));
|
||||
assert(data_sizeof() == sizeof(ImageHandle));
|
||||
assert(buffer.size() == 0);
|
||||
|
||||
char *data = (char *)&f;
|
||||
size_t size = sizeof(f);
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
buffer.push_back(data[i]);
|
||||
buffer.resize(sizeof(ImageHandle));
|
||||
new (buffer.data()) ImageHandle(handle);
|
||||
}
|
||||
|
||||
void Attribute::add(const char *data)
|
||||
@@ -145,7 +140,7 @@ void Attribute::add(const char *data)
|
||||
size_t Attribute::data_sizeof() const
|
||||
{
|
||||
if (element == ATTR_ELEMENT_VOXEL)
|
||||
return sizeof(VoxelAttribute);
|
||||
return sizeof(ImageHandle);
|
||||
else if (element == ATTR_ELEMENT_CORNER_BYTE)
|
||||
return sizeof(uchar4);
|
||||
else if (type == TypeDesc::TypeFloat)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef __ATTRIBUTE_H__
|
||||
#define __ATTRIBUTE_H__
|
||||
|
||||
#include "render/image.h"
|
||||
|
||||
#include "kernel/kernel_types.h"
|
||||
|
||||
#include "util/util_list.h"
|
||||
@@ -31,19 +33,12 @@ class Attribute;
|
||||
class AttributeRequest;
|
||||
class AttributeRequestSet;
|
||||
class AttributeSet;
|
||||
class ImageManager;
|
||||
class ImageHandle;
|
||||
class Geometry;
|
||||
class Hair;
|
||||
class Mesh;
|
||||
struct Transform;
|
||||
|
||||
/* Attributes for voxels are images */
|
||||
|
||||
struct VoxelAttribute {
|
||||
ImageManager *manager;
|
||||
int slot;
|
||||
};
|
||||
|
||||
/* Attribute
|
||||
*
|
||||
* Arbitrary data layers on meshes.
|
||||
@@ -105,10 +100,12 @@ class Attribute {
|
||||
assert(data_sizeof() == sizeof(Transform));
|
||||
return (Transform *)data();
|
||||
}
|
||||
VoxelAttribute *data_voxel()
|
||||
|
||||
/* Attributes for voxels are images */
|
||||
ImageHandle &data_voxel()
|
||||
{
|
||||
assert(data_sizeof() == sizeof(VoxelAttribute));
|
||||
return (VoxelAttribute *)data();
|
||||
assert(data_sizeof() == sizeof(ImageHandle));
|
||||
return *(ImageHandle *)data();
|
||||
}
|
||||
|
||||
const char *data() const
|
||||
@@ -140,10 +137,10 @@ class Attribute {
|
||||
assert(data_sizeof() == sizeof(Transform));
|
||||
return (const Transform *)data();
|
||||
}
|
||||
const VoxelAttribute *data_voxel() const
|
||||
const ImageHandle &data_voxel() const
|
||||
{
|
||||
assert(data_sizeof() == sizeof(VoxelAttribute));
|
||||
return (const VoxelAttribute *)data();
|
||||
assert(data_sizeof() == sizeof(ImageHandle));
|
||||
return *(const ImageHandle *)data();
|
||||
}
|
||||
|
||||
void zero_data(void *dst);
|
||||
@@ -153,8 +150,8 @@ class Attribute {
|
||||
void add(const float2 &f);
|
||||
void add(const float3 &f);
|
||||
void add(const uchar4 &f);
|
||||
void add(const Transform &f);
|
||||
void add(const VoxelAttribute &f);
|
||||
void add(const Transform &tfm);
|
||||
void add(const ImageHandle &handle);
|
||||
void add(const char *data);
|
||||
|
||||
static bool same_storage(TypeDesc a, TypeDesc b);
|
||||
|
||||
@@ -534,8 +534,8 @@ static void update_attribute_element_offset(Geometry *geom,
|
||||
|
||||
if (mattr->element == ATTR_ELEMENT_VOXEL) {
|
||||
/* store slot in offset value */
|
||||
VoxelAttribute *voxel_data = mattr->data_voxel();
|
||||
offset = voxel_data->slot;
|
||||
ImageHandle &handle = mattr->data_voxel();
|
||||
offset = handle.svm_slot();
|
||||
}
|
||||
else if (mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
|
||||
uchar4 *data = mattr->data_uchar4();
|
||||
@@ -1143,7 +1143,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
|
||||
}
|
||||
|
||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||
create_volume_mesh(scene, mesh, progress);
|
||||
create_volume_mesh(mesh, progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1171,7 +1171,8 @@ void GeometryManager::device_update_displacement_images(Device *device,
|
||||
}
|
||||
|
||||
ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode *>(node);
|
||||
foreach (int slot, image_node->slots) {
|
||||
for (int i = 0; i < image_node->handle.num_tiles(); i++) {
|
||||
const int slot = image_node->handle.svm_slot(i);
|
||||
if (slot != -1) {
|
||||
bump_images.insert(slot);
|
||||
}
|
||||
@@ -1204,10 +1205,10 @@ void GeometryManager::device_update_volume_images(Device *device, Scene *scene,
|
||||
continue;
|
||||
}
|
||||
|
||||
VoxelAttribute *voxel = attr.data_voxel();
|
||||
|
||||
if (voxel->slot != -1) {
|
||||
volume_images.insert(voxel->slot);
|
||||
ImageHandle &handle = attr.data_voxel();
|
||||
const int slot = handle.svm_slot();
|
||||
if (slot != -1) {
|
||||
volume_images.insert(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ class GeometryManager {
|
||||
protected:
|
||||
bool displace(Device *device, DeviceScene *dscene, Scene *scene, Mesh *mesh, Progress &progress);
|
||||
|
||||
void create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress);
|
||||
void create_volume_mesh(Mesh *mesh, Progress &progress);
|
||||
|
||||
/* Attributes */
|
||||
void update_osl_attributes(Device *device,
|
||||
|
||||
@@ -79,6 +79,92 @@ const char *name_from_type(ImageDataType type)
|
||||
|
||||
} // namespace
|
||||
|
||||
/* Image Handle */
|
||||
|
||||
ImageHandle::ImageHandle() : manager(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
ImageHandle::ImageHandle(const ImageHandle &other) : slots(other.slots), manager(other.manager)
|
||||
{
|
||||
/* Increase image user count. */
|
||||
foreach (const int slot, slots) {
|
||||
manager->add_image_user(slot);
|
||||
}
|
||||
}
|
||||
|
||||
ImageHandle &ImageHandle::operator=(const ImageHandle &other)
|
||||
{
|
||||
clear();
|
||||
manager = other.manager;
|
||||
slots = other.slots;
|
||||
|
||||
foreach (const int slot, slots) {
|
||||
manager->add_image_user(slot);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ImageHandle::~ImageHandle()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void ImageHandle::clear()
|
||||
{
|
||||
foreach (const int slot, slots) {
|
||||
manager->remove_image_user(slot);
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageHandle::empty()
|
||||
{
|
||||
return slots.empty();
|
||||
}
|
||||
|
||||
int ImageHandle::num_tiles()
|
||||
{
|
||||
return slots.size();
|
||||
}
|
||||
|
||||
ImageMetaData ImageHandle::metadata()
|
||||
{
|
||||
if (slots.empty()) {
|
||||
return ImageMetaData();
|
||||
}
|
||||
|
||||
return manager->images[slots.front()]->metadata;
|
||||
}
|
||||
|
||||
int ImageHandle::svm_slot(const int tile_index)
|
||||
{
|
||||
if (tile_index >= slots.size()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (manager->osl_texture_system) {
|
||||
ImageManager::Image *img = manager->images[slots[tile_index]];
|
||||
if (!img->key.builtin_data) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return slots[tile_index];
|
||||
}
|
||||
|
||||
device_memory *ImageHandle::image_memory(const int tile_index)
|
||||
{
|
||||
if (tile_index >= slots.size()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ImageManager::Image *img = manager->images[slots[tile_index]];
|
||||
return img ? img->mem : NULL;
|
||||
}
|
||||
|
||||
/* Image Manager */
|
||||
|
||||
ImageManager::ImageManager(const DeviceInfo &info)
|
||||
{
|
||||
need_update = true;
|
||||
@@ -86,10 +172,7 @@ ImageManager::ImageManager(const DeviceInfo &info)
|
||||
animation_frame = 0;
|
||||
|
||||
/* Set image limits */
|
||||
max_num_images = TEX_NUM_MAX;
|
||||
has_half_images = info.has_half_images;
|
||||
|
||||
tex_num_images = 0;
|
||||
}
|
||||
|
||||
ImageManager::~ImageManager()
|
||||
@@ -117,31 +200,6 @@ bool ImageManager::set_animation_frame_update(int frame)
|
||||
return false;
|
||||
}
|
||||
|
||||
device_memory *ImageManager::image_memory(int slot)
|
||||
{
|
||||
if (slot == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Image *img = images[slot];
|
||||
return img ? img->mem : NULL;
|
||||
}
|
||||
|
||||
bool ImageManager::get_image_metadata(int slot, ImageMetaData &metadata)
|
||||
{
|
||||
if (slot == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Image *img = images[slot];
|
||||
if (img) {
|
||||
metadata = img->metadata;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ImageManager::metadata_detect_colorspace(ImageMetaData &metadata, const char *file_format)
|
||||
{
|
||||
/* Convert used specified color spaces to one we know how to handle. */
|
||||
@@ -174,7 +232,7 @@ void ImageManager::metadata_detect_colorspace(ImageMetaData &metadata, const cha
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageManager::get_image_metadata(const ImageKey &key, ImageMetaData &metadata)
|
||||
bool ImageManager::load_image_metadata(const ImageKey &key, ImageMetaData &metadata)
|
||||
{
|
||||
metadata = ImageMetaData();
|
||||
metadata.colorspace = key.colorspace;
|
||||
@@ -267,12 +325,37 @@ bool ImageManager::get_image_metadata(const ImageKey &key, ImageMetaData &metada
|
||||
return true;
|
||||
}
|
||||
|
||||
int ImageManager::add_image(const ImageKey &key, float frame, ImageMetaData &metadata)
|
||||
ImageHandle ImageManager::add_image(const ImageKey &key, float frame)
|
||||
{
|
||||
ImageHandle handle;
|
||||
handle.slots.push_back(add_image_slot(key, frame));
|
||||
handle.manager = this;
|
||||
return handle;
|
||||
}
|
||||
|
||||
ImageHandle ImageManager::add_image(const ImageKey &key, float frame, const vector<int> &tiles)
|
||||
{
|
||||
ImageHandle handle;
|
||||
handle.manager = this;
|
||||
|
||||
foreach (int tile, tiles) {
|
||||
ImageKey tile_key = key;
|
||||
if (tile != 0) {
|
||||
string_replace(tile_key.filename, "<UDIM>", string_printf("%04d", tile));
|
||||
}
|
||||
handle.slots.push_back(add_image_slot(tile_key, frame));
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
int ImageManager::add_image_slot(const ImageKey &key, float frame)
|
||||
{
|
||||
Image *img;
|
||||
size_t slot;
|
||||
|
||||
get_image_metadata(key, metadata);
|
||||
ImageMetaData metadata;
|
||||
load_image_metadata(key, metadata);
|
||||
|
||||
thread_scoped_lock device_lock(device_mutex);
|
||||
|
||||
@@ -309,19 +392,6 @@ int ImageManager::add_image(const ImageKey &key, float frame, ImageMetaData &met
|
||||
break;
|
||||
}
|
||||
|
||||
/* Count if we're over the limit.
|
||||
* Very unlikely, since max_num_images is insanely big. But better safe
|
||||
* than sorry.
|
||||
*/
|
||||
if (tex_num_images > max_num_images) {
|
||||
printf(
|
||||
"ImageManager::add_image: Reached image limit (%d), "
|
||||
"skipping '%s'\n",
|
||||
max_num_images,
|
||||
key.filename.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (slot == images.size()) {
|
||||
images.resize(images.size() + 1);
|
||||
}
|
||||
@@ -337,8 +407,6 @@ int ImageManager::add_image(const ImageKey &key, float frame, ImageMetaData &met
|
||||
|
||||
images[slot] = img;
|
||||
|
||||
++tex_num_images;
|
||||
|
||||
need_update = true;
|
||||
|
||||
return slot;
|
||||
@@ -352,7 +420,7 @@ void ImageManager::add_image_user(int slot)
|
||||
image->users++;
|
||||
}
|
||||
|
||||
void ImageManager::remove_image(int slot)
|
||||
void ImageManager::remove_image_user(int slot)
|
||||
{
|
||||
Image *image = images[slot];
|
||||
assert(image && image->users >= 1);
|
||||
@@ -367,32 +435,6 @@ void ImageManager::remove_image(int slot)
|
||||
need_update = true;
|
||||
}
|
||||
|
||||
void ImageManager::remove_image(const ImageKey &key)
|
||||
{
|
||||
size_t slot;
|
||||
|
||||
for (slot = 0; slot < images.size(); slot++) {
|
||||
if (images[slot] && images[slot]->key == key) {
|
||||
remove_image(slot);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO(sergey): Deduplicate with the iteration above, but make it pretty,
|
||||
* without bunch of arguments passing around making code readability even
|
||||
* more cluttered.
|
||||
*/
|
||||
void ImageManager::tag_reload_image(const ImageKey &key)
|
||||
{
|
||||
for (size_t slot = 0; slot < images.size(); slot++) {
|
||||
if (images[slot] && images[slot]->key == key) {
|
||||
images[slot]->need_load = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool image_associate_alpha(ImageManager::Image *img)
|
||||
{
|
||||
/* For typical RGBA images we let OIIO convert to associated alpha,
|
||||
@@ -881,7 +923,6 @@ void ImageManager::device_free_image(Device *, int slot)
|
||||
|
||||
delete img;
|
||||
images[slot] = NULL;
|
||||
--tex_num_images;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,9 +941,13 @@ void ImageManager::device_update(Device *device, Scene *scene, Progress &progres
|
||||
device_free_image(device, slot);
|
||||
}
|
||||
else if (images[slot]->need_load) {
|
||||
if (!osl_texture_system || images[slot]->key.builtin_data)
|
||||
if (osl_texture_system && !images[slot]->key.builtin_data) {
|
||||
images[slot]->need_load = false;
|
||||
}
|
||||
else {
|
||||
pool.push(
|
||||
function_bind(&ImageManager::device_load_image, this, device, scene, slot, &progress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,8 +965,12 @@ void ImageManager::device_update_slot(Device *device, Scene *scene, int slot, Pr
|
||||
device_free_image(device, slot);
|
||||
}
|
||||
else if (image->need_load) {
|
||||
if (!osl_texture_system || image->key.builtin_data)
|
||||
if (osl_texture_system && !image->key.builtin_data) {
|
||||
images[slot]->need_load = false;
|
||||
}
|
||||
else {
|
||||
device_load_image(device, scene, slot, progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,18 @@
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Device;
|
||||
class ImageHandle;
|
||||
class ImageKey;
|
||||
class ImageMetaData;
|
||||
class ImageManager;
|
||||
class Progress;
|
||||
class RenderStats;
|
||||
class Scene;
|
||||
class ColorSpaceProcessor;
|
||||
|
||||
/* Image MetaData
|
||||
*
|
||||
* Information about the image that is available before the image pxeisl are loaded. */
|
||||
class ImageMetaData {
|
||||
public:
|
||||
/* Must be set by image file or builtin callback. */
|
||||
@@ -72,6 +79,10 @@ class ImageMetaData {
|
||||
}
|
||||
};
|
||||
|
||||
/* Image Key
|
||||
*
|
||||
* Image description that uniquely identifies and images. When adding images
|
||||
* with the same key, they will be internally deduplicated. */
|
||||
class ImageKey {
|
||||
public:
|
||||
string filename;
|
||||
@@ -101,18 +112,44 @@ class ImageKey {
|
||||
}
|
||||
};
|
||||
|
||||
/* Image Handle
|
||||
*
|
||||
* Access handle for image in the image manager. Multiple shader nodes may
|
||||
* share the same image, and this class handles reference counting for that. */
|
||||
class ImageHandle {
|
||||
public:
|
||||
ImageHandle();
|
||||
ImageHandle(const ImageHandle &other);
|
||||
ImageHandle &operator=(const ImageHandle &other);
|
||||
~ImageHandle();
|
||||
|
||||
void clear();
|
||||
|
||||
bool empty();
|
||||
int num_tiles();
|
||||
|
||||
ImageMetaData metadata();
|
||||
int svm_slot(const int tile_index = 0);
|
||||
device_memory *image_memory(const int tile_index = 0);
|
||||
|
||||
protected:
|
||||
vector<int> slots;
|
||||
ImageManager *manager;
|
||||
|
||||
friend class ImageManager;
|
||||
};
|
||||
|
||||
/* Image Manager
|
||||
*
|
||||
* Handles loading and storage of all images in the scene. This includes 2D
|
||||
* texture images and 3D volume images. */
|
||||
class ImageManager {
|
||||
public:
|
||||
explicit ImageManager(const DeviceInfo &info);
|
||||
~ImageManager();
|
||||
|
||||
int add_image(const ImageKey &key, float frame, ImageMetaData &metadata);
|
||||
void add_image_user(int slot);
|
||||
void remove_image(int slot);
|
||||
void remove_image(const ImageKey &key);
|
||||
void tag_reload_image(const ImageKey &key);
|
||||
bool get_image_metadata(const ImageKey &key, ImageMetaData &metadata);
|
||||
bool get_image_metadata(int slot, ImageMetaData &metadata);
|
||||
ImageHandle add_image(const ImageKey &key, float frame);
|
||||
ImageHandle add_image(const ImageKey &key, float frame, const vector<int> &tiles);
|
||||
|
||||
void device_update(Device *device, Scene *scene, Progress &progress);
|
||||
void device_update_slot(Device *device, Scene *scene, int slot, Progress *progress);
|
||||
@@ -124,8 +161,6 @@ class ImageManager {
|
||||
void set_osl_texture_system(void *texture_system);
|
||||
bool set_animation_frame_update(int frame);
|
||||
|
||||
device_memory *image_memory(int slot);
|
||||
|
||||
void collect_statistics(RenderStats *stats);
|
||||
|
||||
bool need_update;
|
||||
@@ -167,8 +202,6 @@ class ImageManager {
|
||||
};
|
||||
|
||||
private:
|
||||
int tex_num_images;
|
||||
int max_num_images;
|
||||
bool has_half_images;
|
||||
|
||||
thread_mutex device_mutex;
|
||||
@@ -177,6 +210,12 @@ class ImageManager {
|
||||
vector<Image *> images;
|
||||
void *osl_texture_system;
|
||||
|
||||
int add_image_slot(const ImageKey &key, float frame);
|
||||
void add_image_user(int slot);
|
||||
void remove_image_user(int slot);
|
||||
|
||||
bool load_image_metadata(const ImageKey &key, ImageMetaData &metadata);
|
||||
|
||||
bool file_load_image_generic(Image *img, unique_ptr<ImageInput> *in);
|
||||
|
||||
template<TypeDesc::BASETYPE FileFormat, typename StorageType, typename DeviceType>
|
||||
@@ -186,6 +225,8 @@ class ImageManager {
|
||||
|
||||
void device_load_image(Device *device, Scene *scene, int slot, Progress *progress);
|
||||
void device_free_image(Device *device, int slot);
|
||||
|
||||
friend class ImageHandle;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -577,8 +577,8 @@ void LightManager::device_update_background(Device *device,
|
||||
if (node->type == EnvironmentTextureNode::node_type) {
|
||||
EnvironmentTextureNode *env = (EnvironmentTextureNode *)node;
|
||||
ImageMetaData metadata;
|
||||
if (env->image_manager && !env->slots.empty() &&
|
||||
env->image_manager->get_image_metadata(env->slots[0], metadata)) {
|
||||
if (!env->handle.empty()) {
|
||||
ImageMetaData metadata = env->handle.metadata();
|
||||
res.x = max(res.x, metadata.width);
|
||||
res.y = max(res.y, metadata.height);
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ struct VoxelAttributeGrid {
|
||||
int channels;
|
||||
};
|
||||
|
||||
void GeometryManager::create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress)
|
||||
void GeometryManager::create_volume_mesh(Mesh *mesh, Progress &progress)
|
||||
{
|
||||
string msg = string_printf("Computing Volume Mesh %s", mesh->name.c_str());
|
||||
progress.set_status("Updating Mesh", msg);
|
||||
@@ -378,8 +378,8 @@ void GeometryManager::create_volume_mesh(Scene *scene, Mesh *mesh, Progress &pro
|
||||
continue;
|
||||
}
|
||||
|
||||
VoxelAttribute *voxel = attr.data_voxel();
|
||||
device_memory *image_memory = scene->image_manager->image_memory(voxel->slot);
|
||||
ImageHandle &handle = attr.data_voxel();
|
||||
device_memory *image_memory = handle.image_memory();
|
||||
int3 resolution = make_int3(
|
||||
image_memory->data_width, image_memory->data_height, image_memory->data_depth);
|
||||
|
||||
|
||||
@@ -206,27 +206,6 @@ void TextureMapping::compile(OSLCompiler &compiler)
|
||||
|
||||
/* Image Texture */
|
||||
|
||||
ImageSlotTextureNode::~ImageSlotTextureNode()
|
||||
{
|
||||
if (image_manager) {
|
||||
foreach (int slot, slots) {
|
||||
if (slot != -1) {
|
||||
image_manager->remove_image(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageSlotTextureNode::add_image_user() const
|
||||
{
|
||||
/* Increase image user count for new node. */
|
||||
foreach (int slot, slots) {
|
||||
if (slot != -1) {
|
||||
image_manager->add_image_user(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NODE_DEFINE(ImageTextureNode)
|
||||
{
|
||||
NodeType *type = NodeType::add("image_texture", create, NodeType::SHADER);
|
||||
@@ -276,8 +255,6 @@ NODE_DEFINE(ImageTextureNode)
|
||||
|
||||
ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type)
|
||||
{
|
||||
is_float = false;
|
||||
compress_as_srgb = false;
|
||||
colorspace = u_colorspace_raw;
|
||||
builtin_data = NULL;
|
||||
animated = false;
|
||||
@@ -286,17 +263,15 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type)
|
||||
|
||||
ShaderNode *ImageTextureNode::clone() const
|
||||
{
|
||||
add_image_user();
|
||||
return new ImageTextureNode(*this);
|
||||
ImageTextureNode *node = new ImageTextureNode(*this);
|
||||
node->handle = handle;
|
||||
return node;
|
||||
}
|
||||
|
||||
ImageKey ImageTextureNode::image_key(const int tile) const
|
||||
ImageKey ImageTextureNode::image_key() const
|
||||
{
|
||||
ImageKey key;
|
||||
key.filename = filename.string();
|
||||
if (tile != 0) {
|
||||
string_replace(key.filename, "<UDIM>", string_printf("%04d", tile));
|
||||
}
|
||||
key.builtin_data = builtin_data;
|
||||
key.animated = animated;
|
||||
key.interpolation = interpolation;
|
||||
@@ -388,113 +363,81 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
|
||||
ShaderOutput *color_out = output("Color");
|
||||
ShaderOutput *alpha_out = output("Alpha");
|
||||
|
||||
image_manager = compiler.scene->image_manager;
|
||||
if (slots.empty()) {
|
||||
if (handle.empty()) {
|
||||
cull_tiles(compiler.scene, compiler.current_graph);
|
||||
slots.reserve(tiles.size());
|
||||
|
||||
bool have_metadata = false;
|
||||
foreach (int tile, tiles) {
|
||||
ImageKey key = image_key(tile);
|
||||
ImageMetaData metadata;
|
||||
int slot = image_manager->add_image(key, 0, metadata);
|
||||
slots.push_back(slot);
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
handle = image_manager->add_image(image_key(), 0, tiles);
|
||||
}
|
||||
|
||||
/* We assume that all tiles have the same metadata. */
|
||||
if (!have_metadata) {
|
||||
is_float = metadata.is_float;
|
||||
compress_as_srgb = metadata.compress_as_srgb;
|
||||
known_colorspace = metadata.colorspace;
|
||||
have_metadata = true;
|
||||
}
|
||||
/* All tiles have the same metadata. */
|
||||
const ImageMetaData metadata = handle.metadata();
|
||||
const bool compress_as_srgb = metadata.compress_as_srgb;
|
||||
const ustring known_colorspace = metadata.colorspace;
|
||||
|
||||
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
|
||||
uint flags = 0;
|
||||
|
||||
if (compress_as_srgb) {
|
||||
flags |= NODE_IMAGE_COMPRESS_AS_SRGB;
|
||||
}
|
||||
if (!alpha_out->links.empty()) {
|
||||
const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
|
||||
alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
|
||||
alpha_type == IMAGE_ALPHA_IGNORE);
|
||||
|
||||
if (unassociate_alpha) {
|
||||
flags |= NODE_IMAGE_ALPHA_UNASSOCIATE;
|
||||
}
|
||||
}
|
||||
|
||||
bool has_image = false;
|
||||
foreach (int slot, slots) {
|
||||
if (slot != -1) {
|
||||
has_image = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_image) {
|
||||
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
|
||||
uint flags = 0;
|
||||
|
||||
if (compress_as_srgb) {
|
||||
flags |= NODE_IMAGE_COMPRESS_AS_SRGB;
|
||||
}
|
||||
if (!alpha_out->links.empty()) {
|
||||
const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
|
||||
alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
|
||||
alpha_type == IMAGE_ALPHA_IGNORE);
|
||||
|
||||
if (unassociate_alpha) {
|
||||
flags |= NODE_IMAGE_ALPHA_UNASSOCIATE;
|
||||
}
|
||||
}
|
||||
|
||||
if (projection != NODE_IMAGE_PROJ_BOX) {
|
||||
/* If there only is one image (a very common case), we encode it as a negative value. */
|
||||
int num_nodes;
|
||||
if (slots.size() == 1) {
|
||||
num_nodes = -slots[0];
|
||||
}
|
||||
else {
|
||||
num_nodes = divide_up(slots.size(), 2);
|
||||
}
|
||||
|
||||
compiler.add_node(NODE_TEX_IMAGE,
|
||||
num_nodes,
|
||||
compiler.encode_uchar4(vector_offset,
|
||||
compiler.stack_assign_if_linked(color_out),
|
||||
compiler.stack_assign_if_linked(alpha_out),
|
||||
flags),
|
||||
projection);
|
||||
|
||||
if (num_nodes > 0) {
|
||||
for (int i = 0; i < num_nodes; i++) {
|
||||
int4 node;
|
||||
node.x = tiles[2 * i];
|
||||
node.y = slots[2 * i];
|
||||
if (2 * i + 1 < slots.size()) {
|
||||
node.z = tiles[2 * i + 1];
|
||||
node.w = slots[2 * i + 1];
|
||||
}
|
||||
else {
|
||||
node.z = -1;
|
||||
node.w = -1;
|
||||
}
|
||||
compiler.add_node(node.x, node.y, node.z, node.w);
|
||||
}
|
||||
}
|
||||
if (projection != NODE_IMAGE_PROJ_BOX) {
|
||||
/* If there only is one image (a very common case), we encode it as a negative value. */
|
||||
int num_nodes;
|
||||
if (handle.num_tiles() == 1) {
|
||||
num_nodes = -handle.svm_slot();
|
||||
}
|
||||
else {
|
||||
assert(slots.size() == 1);
|
||||
compiler.add_node(NODE_TEX_IMAGE_BOX,
|
||||
slots[0],
|
||||
compiler.encode_uchar4(vector_offset,
|
||||
compiler.stack_assign_if_linked(color_out),
|
||||
compiler.stack_assign_if_linked(alpha_out),
|
||||
flags),
|
||||
__float_as_int(projection_blend));
|
||||
num_nodes = divide_up(handle.num_tiles(), 2);
|
||||
}
|
||||
|
||||
tex_mapping.compile_end(compiler, vector_in, vector_offset);
|
||||
compiler.add_node(NODE_TEX_IMAGE,
|
||||
num_nodes,
|
||||
compiler.encode_uchar4(vector_offset,
|
||||
compiler.stack_assign_if_linked(color_out),
|
||||
compiler.stack_assign_if_linked(alpha_out),
|
||||
flags),
|
||||
projection);
|
||||
|
||||
if (num_nodes > 0) {
|
||||
for (int i = 0; i < num_nodes; i++) {
|
||||
int4 node;
|
||||
node.x = tiles[2 * i];
|
||||
node.y = handle.svm_slot(2 * i);
|
||||
if (2 * i + 1 < tiles.size()) {
|
||||
node.z = tiles[2 * i + 1];
|
||||
node.w = handle.svm_slot(2 * i + 1);
|
||||
}
|
||||
else {
|
||||
node.z = -1;
|
||||
node.w = -1;
|
||||
}
|
||||
compiler.add_node(node.x, node.y, node.z, node.w);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* image not found */
|
||||
if (!color_out->links.empty()) {
|
||||
compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
|
||||
compiler.add_node(
|
||||
NODE_VALUE_V,
|
||||
make_float3(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B));
|
||||
}
|
||||
if (!alpha_out->links.empty())
|
||||
compiler.add_node(
|
||||
NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), compiler.stack_assign(alpha_out));
|
||||
assert(handle.num_tiles() == 1);
|
||||
compiler.add_node(NODE_TEX_IMAGE_BOX,
|
||||
handle.svm_slot(),
|
||||
compiler.encode_uchar4(vector_offset,
|
||||
compiler.stack_assign_if_linked(color_out),
|
||||
compiler.stack_assign_if_linked(alpha_out),
|
||||
flags),
|
||||
__float_as_int(projection_blend));
|
||||
}
|
||||
|
||||
tex_mapping.compile_end(compiler, vector_in, vector_offset);
|
||||
}
|
||||
|
||||
void ImageTextureNode::compile(OSLCompiler &compiler)
|
||||
@@ -503,29 +446,22 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
|
||||
|
||||
tex_mapping.compile(compiler);
|
||||
|
||||
image_manager = compiler.scene->image_manager;
|
||||
if (slots.size() == 0) {
|
||||
ImageMetaData metadata;
|
||||
if (builtin_data == NULL) {
|
||||
ImageKey key = image_key(1001);
|
||||
image_manager->get_image_metadata(key, metadata);
|
||||
slots.push_back(-1);
|
||||
}
|
||||
else {
|
||||
int slot = image_manager->add_image(image_key(), 0, metadata);
|
||||
slots.push_back(slot);
|
||||
}
|
||||
is_float = metadata.is_float;
|
||||
compress_as_srgb = metadata.compress_as_srgb;
|
||||
known_colorspace = metadata.colorspace;
|
||||
if (handle.empty()) {
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
handle = image_manager->add_image(image_key(), 0);
|
||||
}
|
||||
|
||||
if (slots[0] == -1) {
|
||||
const ImageMetaData metadata = handle.metadata();
|
||||
const bool is_float = metadata.is_float;
|
||||
const bool compress_as_srgb = metadata.compress_as_srgb;
|
||||
const ustring known_colorspace = metadata.colorspace;
|
||||
|
||||
if (handle.svm_slot() == -1) {
|
||||
compiler.parameter_texture(
|
||||
"filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
|
||||
}
|
||||
else {
|
||||
compiler.parameter_texture("filename", slots[0]);
|
||||
compiler.parameter_texture("filename", handle.svm_slot());
|
||||
}
|
||||
|
||||
const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
|
||||
@@ -587,8 +523,6 @@ NODE_DEFINE(EnvironmentTextureNode)
|
||||
|
||||
EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(node_type)
|
||||
{
|
||||
is_float = false;
|
||||
compress_as_srgb = false;
|
||||
colorspace = u_colorspace_raw;
|
||||
builtin_data = NULL;
|
||||
animated = false;
|
||||
@@ -596,8 +530,9 @@ EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(node_typ
|
||||
|
||||
ShaderNode *EnvironmentTextureNode::clone() const
|
||||
{
|
||||
add_image_user();
|
||||
return new EnvironmentTextureNode(*this);
|
||||
EnvironmentTextureNode *node = new EnvironmentTextureNode(*this);
|
||||
node->handle = handle;
|
||||
return node;
|
||||
}
|
||||
|
||||
ImageKey EnvironmentTextureNode::image_key() const
|
||||
@@ -632,46 +567,31 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler)
|
||||
ShaderOutput *color_out = output("Color");
|
||||
ShaderOutput *alpha_out = output("Alpha");
|
||||
|
||||
image_manager = compiler.scene->image_manager;
|
||||
if (slots.empty()) {
|
||||
ImageMetaData metadata;
|
||||
int slot = image_manager->add_image(image_key(), 0, metadata);
|
||||
slots.push_back(slot);
|
||||
is_float = metadata.is_float;
|
||||
compress_as_srgb = metadata.compress_as_srgb;
|
||||
known_colorspace = metadata.colorspace;
|
||||
if (handle.empty()) {
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
handle = image_manager->add_image(image_key(), 0);
|
||||
}
|
||||
|
||||
if (slots[0] != -1) {
|
||||
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
|
||||
uint flags = 0;
|
||||
const ImageMetaData metadata = handle.metadata();
|
||||
const bool compress_as_srgb = metadata.compress_as_srgb;
|
||||
const ustring known_colorspace = metadata.colorspace;
|
||||
|
||||
if (compress_as_srgb) {
|
||||
flags |= NODE_IMAGE_COMPRESS_AS_SRGB;
|
||||
}
|
||||
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
|
||||
uint flags = 0;
|
||||
|
||||
compiler.add_node(NODE_TEX_ENVIRONMENT,
|
||||
slots[0],
|
||||
compiler.encode_uchar4(vector_offset,
|
||||
compiler.stack_assign_if_linked(color_out),
|
||||
compiler.stack_assign_if_linked(alpha_out),
|
||||
flags),
|
||||
projection);
|
||||
|
||||
tex_mapping.compile_end(compiler, vector_in, vector_offset);
|
||||
}
|
||||
else {
|
||||
/* image not found */
|
||||
if (!color_out->links.empty()) {
|
||||
compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
|
||||
compiler.add_node(
|
||||
NODE_VALUE_V,
|
||||
make_float3(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B));
|
||||
}
|
||||
if (!alpha_out->links.empty())
|
||||
compiler.add_node(
|
||||
NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), compiler.stack_assign(alpha_out));
|
||||
if (compress_as_srgb) {
|
||||
flags |= NODE_IMAGE_COMPRESS_AS_SRGB;
|
||||
}
|
||||
|
||||
compiler.add_node(NODE_TEX_ENVIRONMENT,
|
||||
handle.svm_slot(),
|
||||
compiler.encode_uchar4(vector_offset,
|
||||
compiler.stack_assign_if_linked(color_out),
|
||||
compiler.stack_assign_if_linked(alpha_out),
|
||||
flags),
|
||||
projection);
|
||||
|
||||
tex_mapping.compile_end(compiler, vector_in, vector_offset);
|
||||
}
|
||||
|
||||
void EnvironmentTextureNode::compile(OSLCompiler &compiler)
|
||||
@@ -681,28 +601,22 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler)
|
||||
/* See comments in ImageTextureNode::compile about support
|
||||
* of builtin images.
|
||||
*/
|
||||
image_manager = compiler.scene->image_manager;
|
||||
if (slots.empty()) {
|
||||
ImageMetaData metadata;
|
||||
if (builtin_data == NULL) {
|
||||
image_manager->get_image_metadata(image_key(), metadata);
|
||||
slots.push_back(-1);
|
||||
}
|
||||
else {
|
||||
int slot = image_manager->add_image(image_key(), 0, metadata);
|
||||
slots.push_back(slot);
|
||||
}
|
||||
is_float = metadata.is_float;
|
||||
compress_as_srgb = metadata.compress_as_srgb;
|
||||
known_colorspace = metadata.colorspace;
|
||||
if (handle.empty()) {
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
handle = image_manager->add_image(image_key(), 0);
|
||||
}
|
||||
|
||||
if (slots[0] == -1) {
|
||||
const ImageMetaData metadata = handle.metadata();
|
||||
const bool is_float = metadata.is_float;
|
||||
const bool compress_as_srgb = metadata.compress_as_srgb;
|
||||
const ustring known_colorspace = metadata.colorspace;
|
||||
|
||||
if (handle.svm_slot() == -1) {
|
||||
compiler.parameter_texture(
|
||||
"filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
|
||||
}
|
||||
else {
|
||||
compiler.parameter_texture("filename", slots[0]);
|
||||
compiler.parameter_texture("filename", handle.svm_slot());
|
||||
}
|
||||
|
||||
compiler.parameter(this, "projection");
|
||||
@@ -1741,16 +1655,11 @@ NODE_DEFINE(PointDensityTextureNode)
|
||||
|
||||
PointDensityTextureNode::PointDensityTextureNode() : ShaderNode(node_type)
|
||||
{
|
||||
image_manager = NULL;
|
||||
slot = -1;
|
||||
builtin_data = NULL;
|
||||
}
|
||||
|
||||
PointDensityTextureNode::~PointDensityTextureNode()
|
||||
{
|
||||
if (image_manager) {
|
||||
image_manager->remove_image(image_key());
|
||||
}
|
||||
}
|
||||
|
||||
ShaderNode *PointDensityTextureNode::clone() const
|
||||
@@ -1758,10 +1667,9 @@ ShaderNode *PointDensityTextureNode::clone() const
|
||||
/* Increase image user count for new node. We need to ensure to not call
|
||||
* add_image again, to work around access of freed data on the Blender
|
||||
* side. A better solution should be found to avoid this. */
|
||||
if (slot != -1) {
|
||||
image_manager->add_image_user(slot);
|
||||
}
|
||||
return new PointDensityTextureNode(*this);
|
||||
PointDensityTextureNode *node = new PointDensityTextureNode(*this);
|
||||
node->handle = handle;
|
||||
return node;
|
||||
}
|
||||
|
||||
void PointDensityTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||
@@ -1772,21 +1680,18 @@ void PointDensityTextureNode::attributes(Shader *shader, AttributeRequestSet *at
|
||||
ShaderNode::attributes(shader, attributes);
|
||||
}
|
||||
|
||||
void PointDensityTextureNode::add_image()
|
||||
void PointDensityTextureNode::add_image(ImageManager *image_manager)
|
||||
{
|
||||
if (slot == -1) {
|
||||
ImageMetaData metadata;
|
||||
slot = image_manager->add_image(image_key(), 0, metadata);
|
||||
if (!handle.empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ImageKey PointDensityTextureNode::image_key() const
|
||||
{
|
||||
ImageKey key;
|
||||
key.filename = filename.string();
|
||||
key.builtin_data = builtin_data;
|
||||
key.interpolation = interpolation;
|
||||
return key;
|
||||
|
||||
handle = image_manager->add_image(key, 0);
|
||||
}
|
||||
|
||||
void PointDensityTextureNode::compile(SVMCompiler &compiler)
|
||||
@@ -1798,11 +1703,10 @@ void PointDensityTextureNode::compile(SVMCompiler &compiler)
|
||||
const bool use_density = !density_out->links.empty();
|
||||
const bool use_color = !color_out->links.empty();
|
||||
|
||||
image_manager = compiler.scene->image_manager;
|
||||
|
||||
if (use_density || use_color) {
|
||||
add_image();
|
||||
add_image(compiler.scene->image_manager);
|
||||
|
||||
const int slot = handle.svm_slot();
|
||||
if (slot != -1) {
|
||||
compiler.stack_assign(vector_in);
|
||||
compiler.add_node(NODE_TEX_VOXEL,
|
||||
@@ -1839,12 +1743,10 @@ void PointDensityTextureNode::compile(OSLCompiler &compiler)
|
||||
const bool use_density = !density_out->links.empty();
|
||||
const bool use_color = !color_out->links.empty();
|
||||
|
||||
image_manager = compiler.scene->image_manager;
|
||||
|
||||
if (use_density || use_color) {
|
||||
add_image();
|
||||
add_image(compiler.scene->image_manager);
|
||||
|
||||
compiler.parameter_texture("filename", slot);
|
||||
compiler.parameter_texture("filename", handle.svm_slot());
|
||||
if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
|
||||
compiler.parameter("mapping", tfm);
|
||||
compiler.parameter("use_mapping", 1);
|
||||
|
||||
@@ -78,12 +78,9 @@ class ImageSlotTextureNode : public TextureNode {
|
||||
explicit ImageSlotTextureNode(const NodeType *node_type) : TextureNode(node_type)
|
||||
{
|
||||
special_type = SHADER_SPECIAL_TYPE_IMAGE_SLOT;
|
||||
image_manager = NULL;
|
||||
}
|
||||
~ImageSlotTextureNode();
|
||||
void add_image_user() const;
|
||||
ImageManager *image_manager;
|
||||
vector<int> slots;
|
||||
|
||||
ImageHandle handle;
|
||||
};
|
||||
|
||||
class ImageTextureNode : public ImageSlotTextureNode {
|
||||
@@ -103,7 +100,7 @@ class ImageTextureNode : public ImageSlotTextureNode {
|
||||
animated == image_node.animated;
|
||||
}
|
||||
|
||||
ImageKey image_key(const int tile = 0) const;
|
||||
ImageKey image_key() const;
|
||||
|
||||
/* Parameters. */
|
||||
ustring filename;
|
||||
@@ -118,11 +115,6 @@ class ImageTextureNode : public ImageSlotTextureNode {
|
||||
float3 vector;
|
||||
ccl::vector<int> tiles;
|
||||
|
||||
/* Runtime. */
|
||||
bool is_float;
|
||||
bool compress_as_srgb;
|
||||
ustring known_colorspace;
|
||||
|
||||
protected:
|
||||
void cull_tiles(Scene *scene, ShaderGraph *graph);
|
||||
};
|
||||
@@ -159,11 +151,6 @@ class EnvironmentTextureNode : public ImageSlotTextureNode {
|
||||
InterpolationType interpolation;
|
||||
bool animated;
|
||||
float3 vector;
|
||||
|
||||
/* Runtime. */
|
||||
bool is_float;
|
||||
bool compress_as_srgb;
|
||||
ustring known_colorspace;
|
||||
};
|
||||
|
||||
class SkyTextureNode : public TextureNode {
|
||||
@@ -370,9 +357,7 @@ class PointDensityTextureNode : public ShaderNode {
|
||||
return true;
|
||||
}
|
||||
|
||||
void add_image();
|
||||
|
||||
ImageKey image_key() const;
|
||||
void add_image(ImageManager *image_manager);
|
||||
|
||||
/* Parameters. */
|
||||
ustring filename;
|
||||
@@ -383,8 +368,7 @@ class PointDensityTextureNode : public ShaderNode {
|
||||
void *builtin_data;
|
||||
|
||||
/* Runtime. */
|
||||
ImageManager *image_manager;
|
||||
int slot;
|
||||
ImageHandle handle;
|
||||
|
||||
virtual bool equals(const ShaderNode &other)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user