Skip to content

Commit eba922c

Browse files
author
devsh
committed
it actually works for access chains!
1 parent 4de03b9 commit eba922c

File tree

3 files changed

+79
-39
lines changed

3 files changed

+79
-39
lines changed

include/nbl/builtin/hlsl/bda/__ptr.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct __ptr
5353
{
5454
// TODO: assert(addr&uint64_t(alignment-1)==0);
5555
__ref<T,alignment,false> retval;
56-
retval.__init(spirv::bitcast<__spv_ptr_t<T>,uint32_t2>(addr));
56+
retval.__init(spirv::bitcast<spirv::bda_pointer_t<T>,uint32_t2>(addr));
5757
return retval;
5858
}
5959

include/nbl/builtin/hlsl/bda/__ref.hlsl

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,58 +13,46 @@ namespace hlsl
1313
namespace bda
1414
{
1515

16-
template<typename T, uint32_t alignment, bool _restrict>
17-
struct __base_ref;
18-
template<typename T, uint32_t alignment>
19-
struct __base_ref<T,alignment,false>
16+
template<typename T, bool _restrict>
17+
struct __spv_ptr_t;
18+
template<typename T>
19+
struct __spv_ptr_t<T,false>
2020
{
21-
[[vk::ext_decorate(spv::DecorationAliasedPointer)]] spirv::bda_pointer_t<T> ptr;
22-
23-
void __init(const spirv::bda_pointer_t<T> _ptr)
24-
{
25-
ptr = _ptr;
26-
}
27-
28-
spirv::bda_pointer_t<T> __get_spv_ptr()
29-
{
30-
// BUG: if I don't launder the pointer through this I get ""
31-
return spirv::bitcast<spirv::bda_pointer_t<T> >(spirv::bitcast<uint32_t2>(ptr));
32-
}
33-
34-
T load()
35-
{
36-
return spirv::load<T,alignment>(__get_spv_ptr());
37-
}
38-
39-
void store(const T val)
40-
{
41-
spirv::store<T,alignment>(__get_spv_ptr(), val);
42-
}
21+
[[vk::ext_decorate(spv::DecorationAliasedPointer)]] spirv::bda_pointer_t<T> value;
4322
};
44-
template<typename T, uint32_t alignment>
45-
struct __base_ref<T,alignment,true>
23+
template<typename T>
24+
struct __spv_ptr_t<T,true>
4625
{
47-
[[vk::ext_decorate(spv::DecorationRestrictPointer)]] spirv::bda_pointer_t<T> ptr;
26+
[[vk::ext_decorate(spv::DecorationRestrictPointer)]] spirv::bda_pointer_t<T> value;
27+
};
28+
29+
template<typename T, uint32_t alignment, bool _restrict>
30+
struct __base_ref
31+
{
32+
__spv_ptr_t<T,_restrict> ptr;
4833

4934
void __init(const spirv::bda_pointer_t<T> _ptr)
5035
{
51-
ptr = _ptr;
36+
ptr.value = _ptr;
5237
}
5338

5439
spirv::bda_pointer_t<T> __get_spv_ptr()
5540
{
56-
// BUG: if I don't launder the pointer through this I get ""
57-
return spirv::bitcast<spirv::bda_pointer_t<T> >(spirv::bitcast<uint32_t2>(ptr));
41+
// BUG: if I don't launder the pointer through this I get "IsNonPtrAccessChain(ptrInst->opcode())"
42+
//return ptr.value;
43+
// What to do!? OpCopyObject? trick the compiler into giving me an immediate value some other way!?
44+
// If I add `[[vk::ext_reference]]` to my OpLoad and OpStore, then compiler doesn't emit anything!?
45+
return spirv::bitcast<spirv::bda_pointer_t<T> >(spirv::bitcast<uint32_t2>(ptr.value));
5846
}
5947

6048
T load()
6149
{
62-
return spirv::load<T,alignment>(__get_spv_ptr() );
50+
return spirv::load<T,alignment>(__get_spv_ptr());
6351
}
6452

6553
void store(const T val)
6654
{
67-
spirv::store<T,alignment>(__get_spv_ptr(), val);
55+
spirv::store<T,alignment>(__get_spv_ptr(),val);
6856
}
6957
};
7058

@@ -81,4 +69,53 @@ struct __ref : __base_ref<T,alignment,_restrict>
8169

8270
// time for some macros!
8371
// Sequence of (variableName,Type)
72+
// need to gen identical struct in HLSL and C++
73+
/*
74+
struct MyStruct
75+
{
76+
// TODO: compute offsets from sizes and alignments
77+
[[vk::ext_decorate(spv::DecorationOffset,0)]] float32_t a;
78+
[[vk::ext_decorate(spv::DecorationOffset,4)]] int32_t b;
79+
[[vk::ext_decorate(spv::DecorationOffset,8)]] int16_t2 c;
80+
};
81+
template<>
82+
struct nbl::hlsl::alignment_of<MyStruct>
83+
{
84+
// TODO: compute alignment if not user specified
85+
NBL_CONSTEXPR_STATIC_INLINE uint32_t value = 4;
86+
};
87+
template<<>
88+
struct nbl::hlsl::impl::member_info<MyStruct,0>
89+
{
90+
using type = float32_t;
91+
NBL_CONSTEXPR_STATIC_INLINE uint32_t offset = 0;
92+
};
93+
template<>
94+
struct nbl::hlsl::impl::member_info<MyStruct,1>
95+
{
96+
using type = int32_t;
97+
NBL_CONSTEXPR_STATIC_INLINE uint32_t offset = nbl::hlsl::mpl::round_up<member_info<MyStruct,0>::offset+sizeof(member_info<MyStruct,0>::type),alignof<type> >::value;
98+
};
99+
100+
101+
template<uint32_t alignment, bool _restrict>
102+
struct nbl::hlsl::bda::__ref<MyStruct,alignment,_restrict> : nbl::hlsl::bda::__base_ref<MyStruct,alignment,_restrict>
103+
{
104+
using base_t = __base_ref<MyStruct,alignment,_restrict>;
105+
using this_t = __ref<MyStruct,alignment,_restrict>;
106+
107+
// TODO: compute alignment as min of base alignment and offset alignment
108+
nbl::hlsl::bda::__ref<float32_t,1,_restrict> a;
109+
nbl::hlsl::bda::__ref<int32_t,1,_restrict> b;
110+
nbl::hlsl::bda::__ref<int16_t2,1,_restrict> c;
111+
112+
void __init(const nbl::hlsl::spirv::bda_pointer_t<MyStruct> _ptr)
113+
{
114+
base_t::__init(_ptr);
115+
a.__init(spirv::accessChain<float32_t>(base_t::__get_spv_ptr(),0));
116+
b.__init(spirv::accessChain<int32_t>(base_t::__get_spv_ptr(),1));
117+
c.__init(spirv::accessChain<int16_t2>(base_t::__get_spv_ptr(),2));
118+
}
119+
};
120+
*/
84121
#endif

include/nbl/builtin/hlsl/spirv_intrinsics/core.hlsl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,16 @@ static const uint32_t LocalInvocationIndex;
9191
template<uint32_t StorageClass, typename T>
9292
using pointer_t = vk::SpirvOpaqueType<spv::OpTypePointer,vk::Literal<vk::integral_constant<uint32_t,StorageClass> >,T>;
9393

94+
template<typename T>
95+
using bda_pointer_t __NBL_CAPABILITY_PhysicalStorageBufferAddresses = vk::SpirvType<spv::OpTypePointer, sizeof(uint64_t),/*alignof(uint64_t)*/8, vk::Literal<vk::integral_constant<uint32_t, spv::StorageClassPhysicalStorageBuffer> >, T>;
96+
97+
9498
//! General Operations
9599

96100
//
101+
template<typename M, typename T>
102+
[[vk::ext_instruction(spv::OpAccessChain)]]
103+
bda_pointer_t<M> accessChain(bda_pointer_t<T> v, int32_t index);
97104
template<typename M, uint32_t StorageClass, typename T>
98105
[[vk::ext_instruction(spv::OpAccessChain)]]
99106
pointer_t<StorageClass,M> accessChain(pointer_t<StorageClass,T> v, int32_t index);
@@ -222,10 +229,6 @@ template<typename T, typename Ptr_T> // DXC Workaround
222229
enable_if_t<is_spirv_type_v<Ptr_T>, T> atomicCompareExchange(Ptr_T ptr, uint32_t memoryScope, uint32_t memSemanticsEqual, uint32_t memSemanticsUnequal, T value, T comparator);
223230

224231

225-
226-
template<typename T>
227-
using bda_pointer_t __NBL_CAPABILITY_PhysicalStorageBufferAddresses = vk::SpirvType<spv::OpTypePointer,sizeof(uint64_t),/*alignof(uint64_t)*/8,vk::Literal<vk::integral_constant<uint32_t,spv::StorageClassPhysicalStorageBuffer> >,T>;
228-
229232
template<typename T, uint32_t alignment>
230233
__NBL_CAPABILITY_PhysicalStorageBufferAddresses
231234
[[vk::ext_instruction(spv::OpLoad)]]

0 commit comments

Comments
 (0)