Files
workinf_Blender_Wasm/blender-5.2.0/intern/cycles/kernel/osl/services.h
2026-08-12 04:47:48 -04:00

299 lines
11 KiB
C++

/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
/* OSL Render Services
*
* Implementation of OSL render services, to retriever matrices, attributes,
* textures and point clouds. In principle this should only be accessing
* kernel data, but currently we also reach back into the Scene to retrieve
* attributes.
*/
#include <OSL/oslclosure.h>
#include <OSL/oslexec.h>
#include <OSL/rendererservices.h>
#include <OpenImageIO/unordered_map_concurrent.h>
#include "util/concurrent_set.h"
#include "scene/image.h"
#include "kernel/osl/compat.h"
#include "kernel/osl/types.h"
CCL_NAMESPACE_BEGIN
class Scene;
struct ShaderData;
struct ThreadKernelGlobalsCPU;
/* OSL Texture Handle
*
* OSL texture lookups are string based. If those strings are known at compile
* time, the OSL compiler can cache a texture handle to use instead of a string.
*
* By default it uses TextureSystem::TextureHandle. But since we want to support
* different kinds of textures and color space conversions, this is our own handle
* with additional data.
*
* These are stored in a concurrent hash map, because OSL can compile multiple
* shaders in parallel.
*
* NOTE: The svm_image_texture_ids array contains a compressed mapping of tile to
* svm_image_texture_ids pairs stored as follows: x:tile_a,
* y:svm_image_texture_ids_a, z:tile_b, w:svm_image_texture_ids_b etc. */
struct OSLTextureHandle {
OSLTextureHandle(const OSLTextureHandleType type, const int id = -1) : type(type), id(id) {}
OSLTextureHandle(const ImageHandle &handle) : id(handle.kernel_id()), handle(handle) {}
OSLTextureHandleType type = OSLTextureHandleType::IMAGE;
int id = -1;
ImageHandle handle;
};
using OSLTextureHandleMap = OIIO::unordered_map_concurrent<OSLUStringHash, OSLTextureHandle>;
using OSLTextureFilenameMap = concurrent_set<OSLUStringHash>;
/* OSL Render Services
*
* Interface for OSL to access attributes, textures and other scene data. */
class OSLRenderServices : public OSL::RendererServices {
public:
OSLRenderServices(const int device_type);
~OSLRenderServices() override;
static void register_closures(OSL::ShadingSystem *ss);
int supports(string_view feature) const override;
bool get_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSL::TransformationPtr xform,
float time) override;
bool get_inverse_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSL::TransformationPtr xform,
float time) override;
bool get_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSLUStringHash from,
float time) override;
bool get_inverse_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSLUStringHash to,
float time) override;
bool get_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSL::TransformationPtr xform) override;
bool get_inverse_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSL::TransformationPtr xform) override;
bool get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, OSLUStringHash from) override;
bool get_inverse_matrix(OSL::ShaderGlobals *sg,
OSL::Matrix44 &result,
OSLUStringHash to) override;
bool get_array_attribute(OSL::ShaderGlobals *sg,
bool derivatives,
OSLUStringHash object,
const TypeDesc type,
OSLUStringHash name,
const int index,
void *val) override;
bool get_attribute(OSL::ShaderGlobals *sg,
bool derivatives,
OSLUStringHash object,
const TypeDesc type,
OSLUStringHash name,
void *val) override;
bool get_userdata(bool derivatives,
OSLUStringHash name,
const TypeDesc type,
OSL::ShaderGlobals *sg,
void *val) override;
int pointcloud_search(OSL::ShaderGlobals *sg,
OSLUStringHash filename,
const OSL::Vec3 &center,
const float radius,
const int max_points,
bool sort,
#if OSL_LIBRARY_VERSION_CODE >= 11400
int *out_indices,
#else
size_t *out_indices,
#endif
float *out_distances,
int derivs_offset) override;
int pointcloud_get(OSL::ShaderGlobals *sg,
OSLUStringHash filename,
#if OSL_LIBRARY_VERSION_CODE >= 11400
const int *indices,
#else
size_t *indices,
#endif
const int count,
OSLUStringHash attr_name,
const TypeDesc attr_type,
void *out_data) override;
bool pointcloud_write(OSL::ShaderGlobals *sg,
OSLUStringHash filename,
const OSL::Vec3 &pos,
const int nattribs,
const OSLUStringRep *names,
const TypeDesc *types,
const void **data) override;
bool trace(TraceOpt &options,
OSL::ShaderGlobals *sg,
const OSL::Vec3 &P,
const OSL::Vec3 &dPdx,
const OSL::Vec3 &dPdy,
const OSL::Vec3 &R,
const OSL::Vec3 &dRdx,
const OSL::Vec3 &dRdy) override;
bool getmessage(OSL::ShaderGlobals *sg,
OSLUStringHash source,
OSLUStringHash name,
const TypeDesc type,
void *val,
bool derivatives) override;
OSL::TextureSystem::TextureHandle *get_texture_handle(OSL::ustring filename,
OSL::ShadingContext *context,
const OSL::TextureOpt *options) override;
OSL::TextureSystem::TextureHandle *get_texture_handle(OSLUStringHash filename,
OSL::ShadingContext *context,
const OSL::TextureOpt *options) override;
bool good(OSL::TextureSystem::TextureHandle *texture_handle) override;
bool is_udim(OSL::TextureSystem::TextureHandle *texture_handle) override;
bool texture(OSLUStringHash filename,
OSL::TextureSystem::TextureHandle *texture_handle,
TexturePerthread *texture_thread_info,
OSL::TextureOpt &options,
OSL::ShaderGlobals *sg,
const float s,
const float t,
const float dsdx,
const float dtdx,
const float dsdy,
const float dtdy,
const int nchannels,
float *result,
float *dresultds,
float *dresultdt,
OSLUStringHash *errormessage) override;
bool texture3d(OSLUStringHash filename,
TextureHandle *texture_handle,
TexturePerthread *texture_thread_info,
OSL::TextureOpt &options,
OSL::ShaderGlobals *sg,
const OSL::Vec3 &P,
const OSL::Vec3 &dPdx,
const OSL::Vec3 &dPdy,
const OSL::Vec3 &dPdz,
const int nchannels,
float *result,
float *dresultds,
float *dresultdt,
float *dresultdr,
OSLUStringHash *errormessage) override;
bool environment(OSLUStringHash filename,
TextureHandle *texture_handle,
TexturePerthread *texture_thread_info,
OSL::TextureOpt &options,
OSL::ShaderGlobals *sg,
const OSL::Vec3 &R,
const OSL::Vec3 &dRdx,
const OSL::Vec3 &dRdy,
const int nchannels,
float *result,
float *dresultds,
float *dresultdt,
OSLUStringHash *errormessage) override;
bool get_texture_info(OSLUStringHash filename,
TextureHandle *texture_handle,
TexturePerthread *texture_thread_info,
OSL::ShaderGlobals *sg,
const int subimage,
OSLUStringHash dataname,
const TypeDesc datatype,
void *data,
OSLUStringHash *errormessage) override;
bool get_texture_info(OSLUStringHash filename,
TextureHandle *texture_handle,
float s,
float t,
TexturePerthread *texture_thread_info,
OSL::ShaderGlobals *sg,
const int subimage,
OSLUStringHash dataname,
const TypeDesc datatype,
void *data,
OSLUStringHash *errormessage) override;
static bool get_attribute(ShaderGlobals *globals,
ShaderData *sd,
bool derivatives,
OSLUStringHash object_name,
TypeDesc type,
OSLUStringHash name,
void *val);
static bool get_background_attribute(ShaderGlobals *globals,
ShaderData *sd,
OSLUStringHash name,
TypeDesc type,
bool derivatives,
void *val);
static bool get_camera_attribute(
ShaderGlobals *globals, OSLUStringHash name, TypeDesc type, bool derivatives, void *val);
static bool get_object_standard_attribute(ShaderGlobals *globals,
ShaderData *sd,
OSLUStringHash name,
TypeDesc type,
bool derivatives,
void *val);
/* Texture system and texture handle map are part of the services instead of
* globals to be shared between different render sessions. This saves memory,
* and is required because texture handles are cached as part of the shared
* shading system. */
OSLTextureHandleMap textures;
static ImageManager *image_manager;
private:
int device_type_;
/* We don't support lookup by filename without a handle, which is required anyway
* for GPU, and simplifies the implementation on CPU. This keeps track of the
* ones we have seen to emit a warning only once. */
OSLTextureFilenameMap texture_filenames_seen_;
thread_mutex textures_mutex;
};
CCL_NAMESPACE_END