Add Chromium-only Blender WebEngine parity work
This commit is contained in:
269
blender-5.2.0/intern/cycles/kernel/svm/util.h
Normal file
269
blender-5.2.0/intern/cycles/kernel/svm/util.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kernel/globals.h"
|
||||
#include "kernel/types.h"
|
||||
|
||||
#include "kernel/svm/types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Stack Load */
|
||||
|
||||
ccl_device_inline float stack_load_float(const ccl_private float *stack, const uint a)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
|
||||
return stack[a];
|
||||
}
|
||||
|
||||
ccl_device_inline float stack_load_float_default(const ccl_private float *stack,
|
||||
const uint a,
|
||||
const float value)
|
||||
{
|
||||
return (a == (uint)SVM_STACK_INVALID) ? value : stack_load_float(stack, a);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 stack_load_float3(const ccl_private float *stack, const uint a)
|
||||
{
|
||||
kernel_assert(a + 2 < SVM_STACK_SIZE);
|
||||
|
||||
const ccl_private float *stack_a = stack + a;
|
||||
return make_float3(stack_a[0], stack_a[1], stack_a[2]);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 stack_load_float3_default(const ccl_private float *stack,
|
||||
const uint a,
|
||||
const float3 value)
|
||||
{
|
||||
return (a == (uint)SVM_STACK_INVALID) ? value : stack_load_float3(stack, a);
|
||||
}
|
||||
|
||||
ccl_device_inline int stack_load_int(const ccl_private float *stack, const uint a)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
|
||||
return __float_as_int(stack[a]);
|
||||
}
|
||||
|
||||
/* Type-based stack load. T can be float, float3, dual1, or dual3.
|
||||
* When T is a dual type, derivatives are loaded from adjacent stack slots. */
|
||||
|
||||
template<typename T> ccl_device_inline T stack_load(const ccl_private float *stack, const uint a);
|
||||
|
||||
ccl_device_template_spec float stack_load(const ccl_private float *stack, const uint a)
|
||||
{
|
||||
return stack_load_float(stack, a);
|
||||
}
|
||||
|
||||
ccl_device_template_spec float3 stack_load(const ccl_private float *stack, const uint a)
|
||||
{
|
||||
return stack_load_float3(stack, a);
|
||||
}
|
||||
|
||||
ccl_device_template_spec dual1 stack_load(const ccl_private float *stack, const uint a)
|
||||
{
|
||||
return {
|
||||
stack_load_float(stack, a), stack_load_float(stack, a + 1), stack_load_float(stack, a + 2)};
|
||||
}
|
||||
|
||||
ccl_device_template_spec dual3 stack_load(const ccl_private float *stack, const uint a)
|
||||
{
|
||||
return {stack_load_float3(stack, a),
|
||||
stack_load_float3(stack, a + 3),
|
||||
stack_load_float3(stack, a + 6)};
|
||||
}
|
||||
|
||||
/* Load from SVMInputFloat and SVMInputFloat3. With template versions to support duals
|
||||
* for loading derivatives from adjacent stack slots. */
|
||||
|
||||
ccl_device_inline float stack_load(const ccl_private float *ccl_restrict stack,
|
||||
const SVMInputFloat v)
|
||||
{
|
||||
if ((v.bits >> 8) == (SVM_INPUT_STACK_OFFSET_MASK >> 8)) {
|
||||
return stack_load_float(stack, v.bits & 0xFFu);
|
||||
}
|
||||
return __uint_as_float(v.bits);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 stack_load(const ccl_private float *ccl_restrict stack,
|
||||
const SVMInputFloat3 v)
|
||||
{
|
||||
if ((v.x.bits >> 8) == (SVM_INPUT_STACK_OFFSET_MASK >> 8)) {
|
||||
return stack_load_float3(stack, v.x.bits & 0xFFu);
|
||||
}
|
||||
return make_float3(
|
||||
__uint_as_float(v.x.bits), __uint_as_float(v.y.bits), __uint_as_float(v.z.bits));
|
||||
}
|
||||
|
||||
ccl_device_inline int stack_load(const ccl_private float *stack, const SVMInputInt v)
|
||||
{
|
||||
if (v.offset == SVM_STACK_INVALID) {
|
||||
return v.value;
|
||||
}
|
||||
return stack_load_int(stack, v.offset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ccl_device_inline T stack_load(const ccl_private float *stack, const SVMInputFloat v);
|
||||
|
||||
ccl_device_template_spec float stack_load(const ccl_private float *stack, const SVMInputFloat v)
|
||||
{
|
||||
return stack_load(stack, v);
|
||||
}
|
||||
|
||||
ccl_device_template_spec dual1 stack_load(const ccl_private float *stack, const SVMInputFloat v)
|
||||
{
|
||||
if ((v.bits >> 8) == (SVM_INPUT_STACK_OFFSET_MASK >> 8)) {
|
||||
return stack_load<dual1>(stack, v.bits & 0xFFu);
|
||||
}
|
||||
return dual1(__uint_as_float(v.bits));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ccl_device_inline T stack_load(const ccl_private float *stack, const SVMInputFloat3 v);
|
||||
|
||||
ccl_device_template_spec float3 stack_load(const ccl_private float *stack, const SVMInputFloat3 v)
|
||||
{
|
||||
return stack_load(stack, v);
|
||||
}
|
||||
|
||||
ccl_device_template_spec dual3 stack_load(const ccl_private float *stack, const SVMInputFloat3 v)
|
||||
{
|
||||
if ((v.x.bits >> 8) == (SVM_INPUT_STACK_OFFSET_MASK >> 8)) {
|
||||
return stack_load<dual3>(stack, v.x.bits & 0xFFu);
|
||||
}
|
||||
return dual3(make_float3(
|
||||
__uint_as_float(v.x.bits), __uint_as_float(v.y.bits), __uint_as_float(v.z.bits)));
|
||||
}
|
||||
|
||||
/* Stack Store */
|
||||
|
||||
ccl_device_inline void stack_store_float(ccl_private float *stack, const uint a, const float f)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
|
||||
stack[a] = f;
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store_float3(ccl_private float *stack, const uint a, const float3 f)
|
||||
{
|
||||
kernel_assert(a + 2 < SVM_STACK_SIZE);
|
||||
copy_v3_v3(stack + a, f);
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store_int(ccl_private float *stack, const uint a, const int i)
|
||||
{
|
||||
kernel_assert(a < SVM_STACK_SIZE);
|
||||
|
||||
stack[a] = __int_as_float(i);
|
||||
}
|
||||
|
||||
/* Type-based stack store. Overloaded for plain and dual types.
|
||||
* For dual types, derivatives are stored in adjacent stack slots. */
|
||||
|
||||
ccl_device_inline void stack_store(ccl_private float *stack, const uint a, const float f)
|
||||
{
|
||||
stack_store_float(stack, a, f);
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store(ccl_private float *stack, const uint a, const float3 f)
|
||||
{
|
||||
stack_store_float3(stack, a, f);
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store(ccl_private float *stack, const uint a, const dual1 f)
|
||||
{
|
||||
stack_store_float(stack, a, f.val);
|
||||
stack_store_float(stack, a + 1, f.dx);
|
||||
stack_store_float(stack, a + 2, f.dy);
|
||||
}
|
||||
|
||||
ccl_device_inline void stack_store(ccl_private float *stack, const uint a, const dual3 f)
|
||||
{
|
||||
stack_store_float3(stack, a, f.val);
|
||||
stack_store_float3(stack, a + 3, f.dx);
|
||||
stack_store_float3(stack, a + 6, f.dy);
|
||||
}
|
||||
|
||||
/* Stack Utility */
|
||||
|
||||
ccl_device_inline bool stack_valid(const uint a)
|
||||
{
|
||||
return a != (uint)SVM_STACK_INVALID;
|
||||
}
|
||||
|
||||
/* Reading Nodes */
|
||||
|
||||
/* Read a typed node struct directly from the SVM byte-code stream. The struct T must be a
|
||||
* multiple of sizeof(uint) and its memory layout must match the byte-code encoding. Returns
|
||||
* a const reference into the byte-code array and advances the offset past the struct. */
|
||||
template<typename T>
|
||||
ccl_device_inline const ccl_global T &svm_node_get(KernelGlobals kg, ccl_private int *const offset)
|
||||
{
|
||||
static_assert(alignof(T) <= alignof(uint));
|
||||
static_assert(sizeof(T) % sizeof(uint) == 0);
|
||||
const ccl_global T &node = *reinterpret_cast<const ccl_global T *>(
|
||||
&kernel_data_fetch(svm_nodes, *offset));
|
||||
*offset += sizeof(T) / sizeof(uint);
|
||||
return node;
|
||||
}
|
||||
|
||||
ccl_device_inline float4 svm_node_get_data_float4(KernelGlobals kg, const int offset)
|
||||
{
|
||||
return make_float4(__uint_as_float(kernel_data_fetch(svm_nodes, offset)),
|
||||
__uint_as_float(kernel_data_fetch(svm_nodes, offset + 1)),
|
||||
__uint_as_float(kernel_data_fetch(svm_nodes, offset + 2)),
|
||||
__uint_as_float(kernel_data_fetch(svm_nodes, offset + 3)));
|
||||
}
|
||||
|
||||
/* Shading Helpers */
|
||||
|
||||
ccl_device_forceinline float3 dPdx(const ccl_private ShaderData *sd)
|
||||
{
|
||||
return sd->dPdu * sd->du.dx + sd->dPdv * sd->dv.dx;
|
||||
}
|
||||
|
||||
ccl_device_forceinline float3 dPdy(const ccl_private ShaderData *sd)
|
||||
{
|
||||
return sd->dPdu * sd->du.dy + sd->dPdv * sd->dv.dy;
|
||||
}
|
||||
|
||||
/* Shading position, returns Float3Type = float3 (no derivatives) or dual3 (with derivatives). */
|
||||
|
||||
template<typename Float3Type>
|
||||
ccl_device_inline Float3Type shading_position(const ccl_private ShaderData *sd)
|
||||
{
|
||||
if constexpr (is_dual_v<Float3Type>) {
|
||||
dual3 P(sd->P);
|
||||
P.dx = dPdx(sd);
|
||||
P.dy = dPdy(sd);
|
||||
return P;
|
||||
}
|
||||
else {
|
||||
return sd->P;
|
||||
}
|
||||
}
|
||||
|
||||
/* Shading incoming direction, returns Float3Type = float3 or dual3. */
|
||||
|
||||
template<typename Float3Type>
|
||||
ccl_device_inline Float3Type shading_incoming(const ccl_private ShaderData *sd)
|
||||
{
|
||||
if constexpr (is_dual_v<Float3Type>) {
|
||||
dual3 I(sd->wi);
|
||||
float3 dIdx, dIdy;
|
||||
make_orthonormals(sd->wi, &dIdx, &dIdy);
|
||||
I.dx = sd->dI * dIdx;
|
||||
I.dy = sd->dI * dIdy;
|
||||
return I;
|
||||
}
|
||||
else {
|
||||
return sd->wi;
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
Reference in New Issue
Block a user