summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/hlsl.meta.slang34
-rw-r--r--source/slang/slang-emit-spirv.cpp21
2 files changed, 52 insertions, 3 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 2aa3068fa..87f98adaf 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -24170,6 +24170,7 @@ struct CoopVec<T : __BuiltinArithmeticType, let N : int> : IArray<T>, IArithmeti
//
/// Store all elements of this CoopVec into a buffer at a specified offset.
+ /// Pointer accesses are 16-byte aligned.
/// @param buffer The destination buffer to store the values into.
/// @param byteOffset16ByteAligned The byte offset from the start of the buffer where the data will be stored. Must be 16-byte aligned.
[require(cooperative_vector)]
@@ -24217,6 +24218,18 @@ struct CoopVec<T : __BuiltinArithmeticType, let N : int> : IArray<T>, IArithmeti
}
[ForceInline]
+ [require(spirv, cooperative_vector)]
+ void store(T* buffer, int32_t byteOffset16ByteAligned = 0)
+ {
+ let pointer = Ptr<T[]>(buffer);
+ let alignment = 16;
+ return spirv_asm
+ {
+ OpCooperativeVectorStoreNV $pointer $byteOffset16ByteAligned $this Aligned !alignment;
+ };
+ }
+
+ [ForceInline]
[require(cooperative_vector)]
[require(hlsl_coopvec_poc)]
void store<let M : int>(__ref groupshared T[M] data, int32_t byteOffset16ByteAligned = 0)
@@ -24269,6 +24282,7 @@ struct CoopVec<T : __BuiltinArithmeticType, let N : int> : IArray<T>, IArithmeti
}
/// Load values from a byte-addressable buffer into a cooperative vector.
+ /// Pointer accesses are 16-byte aligned.
/// @param buffer The source buffer to load data from.
/// @param byteOffset16ByteAligned The byte offset from the start of the buffer. Must be 16-byte aligned.
/// @return A new cooperative vector containing the loaded values.
@@ -24368,6 +24382,19 @@ struct CoopVec<T : __BuiltinArithmeticType, let N : int> : IArray<T>, IArithmeti
}
}
+ [ForceInline]
+ [__NoSideEffect]
+ [require(spirv, cooperative_vector)]
+ static CoopVec<T, N> load(T* buffer, int32_t byteOffset16ByteAligned = 0)
+ {
+ let pointer = Ptr<T[]>(buffer);
+ let alignment = 16;
+ return spirv_asm
+ {
+ result:$$CoopVec<T, N> = OpCooperativeVectorLoadNV $pointer $byteOffset16ByteAligned Aligned !alignment;
+ };
+ }
+
// Groupshared
[ForceInline]
[__NoSideEffect]
@@ -25736,6 +25763,13 @@ CoopVec<T, N> coopVecLoad<let N : int, T : __BuiltinArithmeticType>(RWStructured
return CoopVec<T, N>.load(buffer, byteOffset16ByteAligned);
}
+[ForceInline]
+[require(spirv, cooperative_vector)]
+CoopVec<T, N> coopVecLoad<let N : int, T : __BuiltinArithmeticType>(T* buffer, int32_t byteOffset16ByteAligned = 0)
+{
+ return CoopVec<T, N>.load(buffer, byteOffset16ByteAligned);
+}
+
// Groupshared
[ForceInline]
[require(cooperative_vector)]
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 5dfa1c76c..ba238985b 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -2069,10 +2069,25 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
inst->getOp() == kIROp_ArrayType
? emitOpTypeArray(inst, elementType, irArrayType->getElementCount())
: emitOpTypeRuntimeArray(inst, elementType);
- auto strideInst = irArrayType->getArrayStride();
- if (strideInst && shouldEmitArrayStride(irArrayType->getElementType()))
+ if (shouldEmitArrayStride(irArrayType->getElementType()))
{
- int stride = (int)getIntVal(strideInst);
+ auto stride = 0;
+ if (auto strideInst = irArrayType->getArrayStride())
+ {
+ stride = (int)getIntVal(strideInst);
+ }
+ else
+ {
+ // Stride may not have been calculated for basic element types. Calculate it
+ // here.
+ IRSizeAndAlignment sizeAndAlignment;
+ getNaturalSizeAndAlignment(
+ m_targetProgram->getOptionSet(),
+ elementType,
+ &sizeAndAlignment);
+ stride = (int)sizeAndAlignment.getStride();
+ }
+
emitOpDecorateArrayStride(
getSection(SpvLogicalSectionID::Annotations),
nullptr,