Files
test2/intern/cycles/kernel/osl/globals.h
Lukas Stockner e0d14d3b92 Cycles: Refactor: Store Cycles-specific pointers in our own ShaderGlobals
OSL has OSL::ShaderGlobals, which contains all the state for OSL shader
execution. The renderer fills it out and hands a pointer to OSL, and any
callbacks (e.g. for querying attributes) get the pointer back.

In order to store renderer-specific data in it, there's a few opaque pointers
in the struct, but using those has led to a mess of reinterpret_cast<> and
pointer indirection in order to carry all the data around.

However, there is a way to do this nicer: Good old C-style struct inheritance.
In short: Unless you're doing pointer arithmetic, you can just add additional
data at the end of a base struct, and the rest of the code won't care.

In this case, this means that we can have our own ShaderGlobals struct and
add more Cycles-specific data at the end. Additionally, we can replace the
generic opaque void pointers with ones of the correct type, which saves us
from needing to cast them back.

Since we have a copy of ShaderGlobals for GPU OSL anyways, it's just a matter
of refactoring the code a bit to make use of that.

The advantages of this are:
- Avoids casts all over the place, just needs one cast to turn our
  ShaderGlobals into the "base" type that OSL expects and one to turn the
  pointer that OSL gives us on callbacks back into our "derived" type.
- Removes indirection, all the relevant stuff (sd, kg, state) is now
  directly in the ShaderGlobals
- Removes some OSL-specific state from ShaderData, which helps to keep
  memory usage down

Pull Request: https://projects.blender.org/blender/blender/pulls/133689
2025-01-29 01:01:08 +01:00

104 lines
2.2 KiB
C++

/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: Apache-2.0 */
#pragma once
#ifdef WITH_OSL
# include <OSL/oslexec.h>
# include "util/map.h"
# include "util/param.h"
# include "util/vector.h"
# include "kernel/types.h"
# include "kernel/osl/compat.h"
# include "kernel/osl/types.h"
# ifndef WIN32
using std::isfinite;
# endif
CCL_NAMESPACE_BEGIN
class OSLRenderServices;
class ColorSpaceProcessor;
struct ThreadKernelGlobalsCPU;
/* OSL Globals
*
* Data needed by OSL render services, that is global to a rendering session.
* This includes all OSL shaders, name to attribute mapping and texture handles.
*/
struct OSLGlobals {
OSLGlobals()
{
ss = nullptr;
ts = nullptr;
services = nullptr;
use = false;
}
bool use;
/* shading system */
OSL::ShadingSystem *ss;
OSL::TextureSystem *ts;
OSLRenderServices *services;
/* shader states */
vector<OSL::ShaderGroupRef> surface_state;
vector<OSL::ShaderGroupRef> volume_state;
vector<OSL::ShaderGroupRef> displacement_state;
vector<OSL::ShaderGroupRef> bump_state;
OSL::ShaderGroupRef background_state;
/* attributes */
using ObjectNameMap = unordered_map<OSLUStringHash, int>;
ObjectNameMap object_name_map;
vector<ustring> object_names;
};
/* trace() call result */
struct OSLTraceData {
Ray ray;
Intersection isect;
ShaderData sd;
bool setup;
bool init;
bool hit;
};
/* thread key for thread specific data lookup */
struct OSLThreadData {
/* Global Data */
OSLGlobals *globals = nullptr;
OSL::ShadingSystem *ss = nullptr;
/* Per-thread data. */
int thread_index = -1;
mutable ShaderGlobals shader_globals;
mutable OSLTraceData tracedata;
OSL::PerThreadInfo *osl_thread_info = nullptr;
OSL::ShadingContext *context = nullptr;
OIIO::TextureSystem::Perthread *oiio_thread_info = nullptr;
OSLThreadData(OSLGlobals *globals, const int thread_index);
~OSLThreadData();
OSLThreadData(OSLThreadData &other) = delete;
OSLThreadData(OSLThreadData &&other) noexcept;
OSLThreadData &operator=(const OSLThreadData &other) = delete;
OSLThreadData &operator=(OSLThreadData &&other) = delete;
};
CCL_NAMESPACE_END
#endif