23 # include <OSL/oslexec.h>
64 return "nanovdb_float";
66 return "nanovdb_float3";
70 return "nanovdb_fp16";
72 assert(!
"System enumerator type, should never be used");
75 assert(!
"Unhandled image data type");
88 : tile_slots(other.tile_slots), manager(other.manager)
117 manager->remove_image_user(slot);
141 manager->load_image_metadata(img);
151 if (
manager->osl_texture_system) {
166 svm_slots.reserve(num_nodes);
167 for (
size_t i = 0; i < num_nodes; i++) {
171 node.x =
manager->images[slot]->loader->get_tile_number();
176 node.z =
manager->images[slot]->loader->get_tile_number();
184 svm_slots.push_back(
node);
214 if (loader ==
NULL) {
240 colorspace_file_format(
""),
241 use_transform_3d(false),
242 compress_as_srgb(false)
308 return (
a &&
b &&
typeid(*
a) ==
typeid(*
b) &&
a->equals(*
b));
322 osl_texture_system =
NULL;
331 for (
size_t slot = 0; slot < images.size(); slot++)
332 assert(!images[slot]);
337 osl_texture_system = texture_system;
342 if (frame != animation_frame) {
344 animation_frame = frame;
346 for (
size_t slot = 0; slot < images.size(); slot++) {
347 if (images[slot] && images[slot]->
params.animated)
355 void ImageManager::load_image_metadata(
Image *img)
357 if (!img->need_metadata) {
362 if (!img->need_metadata) {
370 if (img->loader->load_metadata(features, metadata)) {
384 img->need_metadata =
false;
405 string tile_filename = filename;
412 int u = ((
tile - 1001) % 10);
413 int v = ((
tile - 1001) / 10);
427 const int slot = add_image_slot(loader,
params, builtin);
440 const int slot = add_image_slot(loader,
params,
true);
448 int ImageManager::add_image_slot(
ImageLoader *loader,
458 for (slot = 0; slot < images.size(); slot++) {
468 for (slot = 0; slot < images.size(); slot++) {
473 if (slot == images.size()) {
474 images.resize(images.size() + 1);
480 img->loader = loader;
481 img->need_metadata =
true;
482 img->need_load = !(osl_texture_system && !img->loader->osl_filepath().empty());
483 img->builtin = builtin;
494 void ImageManager::add_image_user(
int slot)
503 void ImageManager::remove_image_user(
int slot)
515 if (
image->users == 0)
528 template<TypeDesc::BASETYPE FileFormat,
typename StorageType>
529 bool ImageManager::file_load_image(
Image *img,
int texture_limit)
532 if (!(img->metadata.channels > 0)) {
539 int depth = img->metadata.depth;
540 int components = img->metadata.channels;
552 if (texture_limit > 0 && max_size > texture_limit) {
553 pixels_storage.resize(((
size_t)
width) *
height * depth * 4);
554 pixels = &pixels_storage[0];
558 pixels = (StorageType *)img->mem->alloc(
width,
height, depth);
561 if (pixels ==
NULL) {
567 img->loader->load_pixels(
578 const StorageType one = util_image_cast_from_float<StorageType>(1.0f);
580 if (components == 2) {
583 pixels[i * 4 + 3] = pixels[i * 2 + 1];
584 pixels[i * 4 + 2] = pixels[i * 2 + 0];
585 pixels[i * 4 + 1] = pixels[i * 2 + 0];
586 pixels[i * 4 + 0] = pixels[i * 2 + 0];
589 else if (components == 3) {
592 pixels[i * 4 + 3] = one;
593 pixels[i * 4 + 2] = pixels[i * 3 + 2];
594 pixels[i * 4 + 1] = pixels[i * 3 + 1];
595 pixels[i * 4 + 0] = pixels[i * 3 + 0];
598 else if (components == 1) {
601 pixels[i * 4 + 3] = one;
602 pixels[i * 4 + 2] = pixels[i];
603 pixels[i * 4 + 1] = pixels[i];
604 pixels[i * 4 + 0] = pixels[i];
611 pixels[i * 4 + 3] = one;
620 img->metadata.colorspace, pixels,
num_pixels, is_rgba, img->metadata.compress_as_srgb);
630 StorageType *pixel = &pixels[i * 4];
642 StorageType *pixel = &pixels[i];
651 if (pixels_storage.size() > 0) {
652 float scale_factor = 1.0f;
653 while (max_size * scale_factor > texture_limit) {
654 scale_factor *= 0.5f;
656 VLOG_WORK <<
"Scaling image " << img->loader->name() <<
" by a factor of " << scale_factor
659 size_t scaled_width, scaled_height, scaled_depth;
671 StorageType *texture_pixels;
675 texture_pixels = (StorageType *)img->mem->alloc(scaled_width, scaled_height, scaled_depth);
678 memcpy(texture_pixels, &scaled_pixels[0], scaled_pixels.size() *
sizeof(StorageType));
690 Image *img = images[slot];
692 progress->
set_status(
"Updating Images",
"Loading " + img->loader->name());
696 load_image_metadata(img);
710 device, img->mem_name.c_str(), slot,
type, img->params.interpolation, img->params.extension);
711 img->mem->info.use_transform_3d = img->metadata.use_transform_3d;
712 img->mem->info.transform_3d = img->metadata.transform_3d;
716 if (!file_load_image<TypeDesc::FLOAT, float>(img, texture_limit)) {
719 float *pixels = (
float *)img->mem->alloc(1, 1);
728 if (!file_load_image<TypeDesc::FLOAT, float>(img, texture_limit)) {
731 float *pixels = (
float *)img->mem->alloc(1, 1);
737 if (!file_load_image<TypeDesc::UINT8, uchar>(img, texture_limit)) {
740 uchar *pixels = (
uchar *)img->mem->alloc(1, 1);
749 if (!file_load_image<TypeDesc::UINT8, uchar>(img, texture_limit)) {
752 uchar *pixels = (
uchar *)img->mem->alloc(1, 1);
758 if (!file_load_image<TypeDesc::HALF, half>(img, texture_limit)) {
761 half *pixels = (
half *)img->mem->alloc(1, 1);
770 if (!file_load_image<TypeDesc::USHORT, uint16_t>(img, texture_limit)) {
779 if (!file_load_image<TypeDesc::USHORT, uint16_t>(img, texture_limit)) {
791 if (!file_load_image<TypeDesc::HALF, half>(img, texture_limit)) {
794 half *pixels = (
half *)img->mem->alloc(1, 1);
803 void *pixels = img->mem->alloc(img->metadata.byte_size, 0);
805 if (pixels !=
NULL) {
806 img->loader->load_pixels(img->metadata, pixels, img->metadata.byte_size,
false);
813 img->mem->copy_to_device();
817 img->loader->cleanup();
818 img->need_load =
false;
821 void ImageManager::device_free_image(
Device *,
int slot)
823 Image *img = images[slot];
828 if (osl_texture_system) {
830 ustring filepath = img->loader->osl_filepath();
831 if (!filepath.empty()) {
832 ((OSL::TextureSystem *)osl_texture_system)->invalidate(filepath);
855 scene->update_stats->image.times.add_entry({
"device_update", time});
860 for (
size_t slot = 0; slot < images.size(); slot++) {
861 Image *img = images[slot];
862 if (img && img->users == 0) {
863 device_free_image(device, slot);
865 else if (img && img->need_load) {
867 function_bind(&ImageManager::device_load_image,
this, device,
scene, slot, &progress));
873 need_update_ =
false;
878 Image *img = images[slot];
881 if (img->
users == 0) {
882 device_free_image(device, slot);
885 device_load_image(device,
scene, slot, progress);
898 for (
size_t slot = 0; slot < images.size(); slot++) {
899 Image *img = images[slot];
902 function_bind(&ImageManager::device_load_image,
this, device,
scene, slot, &progress));
911 for (
size_t slot = 0; slot < images.size(); slot++) {
912 Image *img = images[slot];
914 device_free_image(device, slot);
921 for (
size_t slot = 0; slot < images.size(); slot++) {
922 device_free_image(device, slot);
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
ATTR_WARN_UNUSED_RESULT const BMVert * v
static bool colorspace_is_data(ustring colorspace)
static void to_scene_linear(ustring colorspace, T *pixels, size_t num_pixels, bool is_rgba, bool compress_as_srgb)
static ustring detect_known_colorspace(ustring colorspace, const char *file_format, bool is_float)
bool operator==(const ImageHandle &other) const
VDBImageLoader * vdb_loader(const int tile_index=0) const
device_texture * image_memory(const int tile_index=0) const
ImageHandle & operator=(const ImageHandle &other)
int svm_slot(const int tile_index=0) const
vector< int4 > get_svm_slots() const
virtual bool equals(const ImageLoader &other) const =0
virtual ustring osl_filepath() const
virtual int get_tile_number() const
virtual bool is_vdb_loader() const
bool set_animation_frame_update(int frame)
ImageManager(const DeviceInfo &info)
void device_update(Device *device, Scene *scene, Progress &progress)
void device_free(Device *device)
void device_load_builtin(Device *device, Scene *scene, Progress &progress)
void device_free_builtin(Device *device)
ImageHandle add_image(const string &filename, const ImageParams ¶ms)
void device_update_slot(Device *device, Scene *scene, int slot, Progress *progress)
void collect_statistics(RenderStats *stats)
void set_osl_texture_system(void *texture_system)
ImageAlphaType alpha_type
void add_entry(const NamedSizeEntry &entry)
void set_status(const string &status_, const string &substatus_="")
ustring u_colorspace_srgb
#define CCL_NAMESPACE_END
CCL_NAMESPACE_BEGIN OIIO_NAMESPACE_USING void util_image_resize_pixels(const vector< T > &input_pixels, const size_t input_width, const size_t input_height, const size_t input_depth, const size_t components, vector< T > *output_pixels, size_t *output_width, size_t *output_height, size_t *output_depth)
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
ccl_gpu_kernel_postfix ccl_global float int num_pixels
ccl_global const KernelWorkTile * tile
const char * name_from_type(ImageDataType type)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static bool image_associate_alpha(ImageManager::Image *img)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
void string_replace(string &haystack, const string &needle, const string &other)
SceneUpdateStats * update_stats
void push(TaskRunFunction &&task)
void wait_work(Summary *stats=NULL)
std::unique_lock< std::mutex > thread_scoped_lock
@ IMAGE_DATA_TYPE_NANOVDB_FP16
@ IMAGE_DATA_TYPE_USHORT4
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT
@ IMAGE_DATA_TYPE_NANOVDB_FLOAT3
@ IMAGE_DATA_TYPE_NANOVDB_FPN
@ IMAGE_ALPHA_CHANNEL_PACKED
#define TEX_IMAGE_MISSING_R
#define TEX_IMAGE_MISSING_B
#define TEX_IMAGE_MISSING_A
#define TEX_IMAGE_MISSING_G
ccl_device_inline size_t divide_up(size_t x, size_t y)