299 lines
11 KiB
C++
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 ¢er,
|
|
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
|