Skip to content

Commit b218c18

Browse files
AlexMWellslgritz
authored andcommitted
Fix batched support for closures with array types (#1630)
Fixed batched support for closures with array types. Enabled testsuite/userdata-custom/BATCHED (follow up to PR1620/PR1621). Added modified version of PR1625 (Fix Issues with Derivative of getattribute) from danieldresser-ie changing default behavior of MaskedData<DataT>::assign_all_from_scalar(const void *) to zero out Dx Dy when DataT has derviatives. Added testsuite/userdata-custom Fixed bug in testshades handling of userdata with derivatives. Added bool LLVM_Util::is_type_array(llvm::Type* type) llvm::Type* LLVM_Util::element_type_of(llvm::Type* array_type) Fixed icx compiler warning with src/liboslexec/osogram.y Fixed unreferenced function warning in src/testrender/shading.cpp Signed-off-by: Alex M. Wells <[email protected]>
1 parent a2b9334 commit b218c18

File tree

13 files changed

+113
-18
lines changed

13 files changed

+113
-18
lines changed

src/cmake/testing.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ macro (osl_add_all_tests)
352352
transform transform-reg transformc transformc-reg trig trig-reg
353353
typecast
354354
unknown-instruction
355-
userdata userdata-passthrough
355+
userdata userdata-custom userdata-passthrough
356356
vararray-connect vararray-default
357357
vararray-deserialize vararray-param
358358
vecctr vector vector-reg

src/include/OSL/llvm_util.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,12 @@ class OSLEXECPUBLIC LLVM_Util {
638638
/// llvm type.
639639
llvm::Type* type_array(llvm::Type* type, int n);
640640

641+
/// Return the true if the llvm::Type is an array
642+
bool is_type_array(llvm::Type* type);
643+
644+
/// Return the llvm::Type of element that the array_type is made up of
645+
llvm::Type* element_type_of(llvm::Type* array_type);
646+
641647
/// Return an llvm::FunctionType that describes a function with the
642648
/// given return types, parameter types (in a cspan), and whether it
643649
/// uses varargs conventions.

src/include/OSL/wide.h

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2845,7 +2845,7 @@ template<int WidthT> class MaskedData {
28452845
// Populate all data lanes of the MaskedData by broadcasting the
28462846
// single instance of data pointed to.
28472847
// Masked off lanes are not overwritten.
2848-
// Includes value, as well as Dx and Dy when has_derivs() is true
2848+
// when has_derivs() is true, Dx and Dy will be zeroed
28492849
OSL_FORCEINLINE void assign_all_from_scalar(const void* ptr_data) const;
28502850

28512851

@@ -2863,6 +2863,9 @@ template<int WidthT> class MaskedData {
28632863
template<typename DataT>
28642864
OSL_NOINLINE void assign_all_from_scalar_type(const void* ptr_data,
28652865
int deriv_index) const;
2866+
2867+
template<typename DataT>
2868+
OSL_NOINLINE void zero_all_type(int deriv_index) const;
28662869
};
28672870

28682871

@@ -3378,6 +3381,33 @@ MaskedData<WidthT>::assign_all_from_scalar_type(const void* ptr_data,
33783381
}
33793382
}
33803383

3384+
template<int WidthT>
3385+
template<typename DataT>
3386+
OSL_NOINLINE void
3387+
MaskedData<WidthT>::zero_all_type(int deriv_index) const
3388+
{
3389+
// We can't just do a memset because some lanes may be masked off
3390+
// Use a SIMD loop to perform masked assignment.
3391+
auto* dst_blocks = pvt::block_cast<DataT, WidthT>(m_ptr);
3392+
int elem_count = static_cast<int>(m_type.numelements());
3393+
int comp_count = m_type.aggregate;
3394+
int deriv_offset = deriv_index * elem_count * comp_count;
3395+
for (int array_index = 0; array_index < elem_count; ++array_index) {
3396+
int array_offset = array_index * comp_count;
3397+
for (int comp_index = 0; comp_index < comp_count; ++comp_index) {
3398+
int combined_index = deriv_offset + array_offset + comp_index;
3399+
auto& bdst = dst_blocks[combined_index];
3400+
3401+
Masked<DataT, WidthT> wdest(bdst, mask());
3402+
3403+
OSL_OMP_PRAGMA(omp simd simdlen(WidthT))
3404+
for (int lane = 0; lane < WidthT; ++lane) {
3405+
wdest[lane] = DataT {};
3406+
}
3407+
}
3408+
}
3409+
}
3410+
33813411
template<int WidthT>
33823412
OSL_FORCEINLINE void
33833413
MaskedData<WidthT>::assign_all_from_scalar(const void* ptr_data) const
@@ -3393,16 +3423,12 @@ MaskedData<WidthT>::assign_all_from_scalar(const void* ptr_data) const
33933423
assign_all_from_scalar_type<ustring>(ptr_data, /*deriv_index*/ 0);
33943424
}
33953425
if (has_derivs()) {
3396-
size_t src_size = type().size();
3397-
const char* dx_src = reinterpret_cast<const char*>(ptr_data) + src_size;
3398-
const char* dy_src = dx_src + src_size;
3399-
34003426
if (isBase32bit) {
3401-
assign_all_from_scalar_type<int>(dx_src, /*deriv_index*/ 1);
3402-
assign_all_from_scalar_type<int>(dy_src, /*deriv_index*/ 2);
3427+
zero_all_type<int>(/*deriv_index*/ 1);
3428+
zero_all_type<int>(/*deriv_index*/ 2);
34033429
} else {
3404-
assign_all_from_scalar_type<ustring>(dx_src, /*deriv_index*/ 1);
3405-
assign_all_from_scalar_type<ustring>(dy_src, /*deriv_index*/ 2);
3430+
zero_all_type<ustring>(/*deriv_index*/ 1);
3431+
zero_all_type<ustring>(/*deriv_index*/ 2);
34063432
}
34073433
}
34083434
}

src/liboslexec/batched_llvm_gen.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7270,15 +7270,40 @@ LLVMGEN(llvm_gen_closure)
72707270
int num_components = simpletype.aggregate;
72717271

72727272
llvm::Value* dest_base = rop.ll.offset_ptr(mem_void_ptr, p.offset);
7273-
dest_base = rop.llvm_ptr_cast(dest_base, p.type);
7273+
llvm::Type* dest_type = rop.ll.llvm_type(
7274+
static_cast<const TypeSpec&>(p.type).simpletype());
7275+
dest_base = rop.ll.ptr_to_cast(dest_base, dest_type);
7276+
7277+
if (num_elements > 1) {
7278+
OSL_DASSERT(rop.ll.is_type_array(dest_type));
7279+
7280+
// The type is an array type,
7281+
// which means our pointer is to an array type,
7282+
// not to &[0] (the address of the 1st element).
7283+
// IE: typedef int Int5Array[5];
7284+
// Int5Array *dest_base;
7285+
// in contrast to what most of use might consider an array pointer
7286+
// int *dest_base;
7287+
// So if we dereference Int5Array* to with [4], the 5th element,
7288+
// we would be really be pointing to ((int *)dest_base)[5*4] which is
7289+
// out of bounds of our 1 instance of Int5Array.
7290+
// Thus when dealing with arrays we will just dereference it and get the address to get
7291+
// the address of the 1st element.
7292+
7293+
dest_base = rop.ll.GEP(dest_type, dest_base, 0, 0);
7294+
llvm::Type* element_type = rop.ll.element_type_of(dest_type);
7295+
dest_type = element_type;
7296+
}
72747297

72757298
for (int a = 0; a < num_elements; ++a) {
72767299
llvm::Value* arrind = simpletype.arraylen ? rop.ll.constant(a)
72777300
: NULL;
72787301
for (int c = 0; c < num_components; c++) {
72797302
llvm::Value* dest_elem;
72807303
if (num_components > 1)
7281-
dest_elem = rop.ll.GEP(dest_base, a, c);
7304+
dest_elem = rop.ll.GEP(dest_type, dest_base, a, c);
7305+
else if (num_elements > 1)
7306+
dest_elem = rop.ll.GEP(dest_type, dest_base, a);
72827307
else
72837308
dest_elem = dest_base;
72847309

src/liboslexec/llvm_util.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,7 +2728,18 @@ LLVM_Util::type_array(llvm::Type* type, int n)
27282728
return llvm::ArrayType::get(type, n);
27292729
}
27302730

2731+
bool
2732+
LLVM_Util::is_type_array(llvm::Type* type)
2733+
{
2734+
return type->isArrayTy();
2735+
}
27312736

2737+
llvm::Type*
2738+
LLVM_Util::element_type_of(llvm::Type* array_type)
2739+
{
2740+
OSL_DASSERT(is_type_array(array_type));
2741+
return array_type->getArrayElementType();
2742+
}
27322743

27332744
llvm::FunctionType*
27342745
LLVM_Util::type_function(llvm::Type* rettype, cspan<llvm::Type*> params,

src/liboslexec/osogram.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#pragma clang diagnostic ignored "-Wparentheses-equality"
2828
#endif
2929

30-
#if OSL_CLANG_VERSION >= 150000
30+
#if (OSL_CLANG_VERSION >= 150000) || (OSL_INTEL_CLANG_VERSION >= 140000)
3131
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
3232
#endif
3333

src/testrender/shading.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,11 @@ struct MxConductorParams : public MxMicrofacetBaseParams {
154154

155155
Color3 evalT(float cos_theta) const { return Color3(0.0f); }
156156

157-
float get_ior() const
158-
{
159-
return 0; // no transmission possible
160-
}
157+
// Avoid function was declared but never referenced
158+
// float get_ior() const
159+
// {
160+
// return 0; // no transmission possible
161+
// }
161162
};
162163

163164
struct MxGeneralizedSchlickParams : public MxMicrofacetBaseParams {

src/testshade/simplerend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ SimpleRenderer::get_userdata(bool derivatives, ustring name, TypeDesc type,
521521
size_t size = p->type().size();
522522
memcpy(val, p->data(), size);
523523
if (derivatives)
524-
memcpy(val, (char*)p->data() + size, 2 * size);
524+
memset((char*)val + size, 0, 2 * size);
525525
return true;
526526
}
527527

testsuite/closure-parameters/BATCHED

Whitespace-only changes.

testsuite/userdata-custom/BATCHED

Whitespace-only changes.

0 commit comments

Comments
 (0)