summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prelude/slang-cuda-prelude.h12
-rw-r--r--source/slang/hlsl.meta.slang161
-rw-r--r--source/slang/slang-emit-cpp.cpp34
-rw-r--r--source/slang/slang-emit-cpp.h2
-rw-r--r--source/slang/slang-emit-cuda.cpp34
-rw-r--r--source/slang/slang-emit-cuda.h1
-rw-r--r--source/slang/slang-emit-glsl.cpp17
-rw-r--r--source/slang/slang-emit-spirv-ops.h14
-rw-r--r--source/slang/slang-emit-spirv.cpp17
-rw-r--r--source/slang/slang-emit.cpp3
-rw-r--r--source/slang/slang-ir-autodiff.cpp1
-rw-r--r--source/slang/slang-ir-lower-buffer-element-type.cpp6
-rw-r--r--tests/compute/byte-address-buffer.slang2
-rw-r--r--tests/compute/unbounded-array-of-array-syntax.slang.glsl6
-rw-r--r--tests/cross-compile/array-of-buffers.slang.glsl11
-rw-r--r--tests/cross-compile/array-of-buffers.slang.hlsl9
-rw-r--r--tests/cross-compile/get-dimensions.slang17
-rw-r--r--tests/cross-compile/get-dimensions.slang.expected.txt2
-rw-r--r--tests/expected-failure.txt4
19 files changed, 286 insertions, 67 deletions
diff --git a/prelude/slang-cuda-prelude.h b/prelude/slang-cuda-prelude.h
index 1447be05b..ad757bdbb 100644
--- a/prelude/slang-cuda-prelude.h
+++ b/prelude/slang-cuda-prelude.h
@@ -1251,7 +1251,9 @@ struct ByteAddressBuffer
SLANG_CUDA_CALL T Load(size_t index) const
{
SLANG_BOUND_CHECK_BYTE_ADDRESS(index, sizeof(T), sizeInBytes);
- return *(const T*)(((const char*)data) + index);
+ T data;
+ memcpy(&data, ((const char*)this->data) + index, sizeof(T));
+ return data;
}
const uint32_t* data;
@@ -1292,7 +1294,9 @@ struct RWByteAddressBuffer
SLANG_CUDA_CALL T Load(size_t index) const
{
SLANG_BOUND_CHECK_BYTE_ADDRESS(index, sizeof(T), sizeInBytes);
- return *(const T*)((const char*)data + index);
+ T data;
+ memcpy(&data, ((const char*)this->data) + index, sizeof(T));
+ return data;
}
SLANG_CUDA_CALL void Store(size_t index, uint32_t v) const
@@ -1328,14 +1332,14 @@ struct RWByteAddressBuffer
SLANG_CUDA_CALL void Store(size_t index, T const& value) const
{
SLANG_BOUND_CHECK_BYTE_ADDRESS(index, sizeof(T), sizeInBytes);
- *(T*)(((char*)data) + index) = value;
+ memcpy((char*)data + index, &value, sizeof(T));
}
/// Can be used in stdlib to gain access
template <typename T>
SLANG_CUDA_CALL T* _getPtrAt(size_t index)
{
- SLANG_BOUND_CHECK_BYTE_ADDRESS(index, sizeof(T), sizeInBytes);
+ SLANG_BOUND_CHECK_BYTE_ADDRESS(index, 4, sizeInBytes);
return (T*)(((char*)data) + index);
}
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index cfc2bc3a5..ec7809b90 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -14,6 +14,15 @@ __generic<T>
__intrinsic_op($(kIROp_StructuredBufferGetDimensions))
uint2 __structuredBufferGetDimensions(ConsumeStructuredBuffer<T> buffer);
+__intrinsic_op($(kIROp_StructuredBufferGetDimensions))
+uint2 __structuredBufferGetDimensions<T>(StructuredBuffer<T> buffer);
+
+__intrinsic_op($(kIROp_StructuredBufferGetDimensions))
+uint2 __structuredBufferGetDimensions<T>(RWStructuredBuffer<T> buffer);
+
+__intrinsic_op($(kIROp_StructuredBufferGetDimensions))
+uint2 __structuredBufferGetDimensions<T>(RasterizerOrderedStructuredBuffer<T> buffer);
+
__generic<T>
__magic_type(HLSLAppendStructuredBufferType)
__intrinsic_type($(kIROp_HLSLAppendStructuredBufferType))
@@ -37,35 +46,61 @@ __magic_type(HLSLByteAddressBufferType)
__intrinsic_type($(kIROp_HLSLByteAddressBufferType))
struct ByteAddressBuffer
{
- __target_intrinsic(glsl, "$1 = $0._data.length() * 4")
[__readNone]
- void GetDimensions(
- out uint dim);
+ __target_intrinsic(hlsl)
+ __target_intrinsic(cpp)
+ __target_intrinsic(cuda)
+ [__unsafeForceInlineEarly]
+ void GetDimensions(out uint dim);
+
+ [__unsafeForceInlineEarly]
+ __specialized_for_target(spirv)
+ __specialized_for_target(glsl)
+ void GetDimensions(out uint dim)
+ {
+ dim = __structuredBufferGetDimensions(__getEquivalentStructuredBuffer<uint>(this)).x*4;
+ }
- __target_intrinsic(glsl, "$0._data[$1/4]")
[__readNone]
- uint Load(int location);
+ [ForceInline]
+ __target_intrinsic(hlsl)
+ uint Load(int location)
+ {
+ return __byteAddressBufferLoad<uint>(this, location);
+ }
[__readNone]
uint Load(int location, out uint status);
- __target_intrinsic(glsl, "uvec2($0._data[$1/4], $0._data[$1/4+1])")
[__readNone]
- uint2 Load2(int location);
+ [ForceInline]
+ __target_intrinsic(hlsl)
+ uint2 Load2(int location)
+ {
+ return __byteAddressBufferLoad<uint2>(this, location);
+ }
[__readNone]
uint2 Load2(int location, out uint status);
- __target_intrinsic(glsl, "uvec3($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2])")
[__readNone]
- uint3 Load3(int location);
+ [ForceInline]
+ __target_intrinsic(hlsl)
+ uint3 Load3(int location)
+ {
+ return __byteAddressBufferLoad<uint3>(this, location);
+ }
[__readNone]
uint3 Load3(int location, out uint status);
- __target_intrinsic(glsl, "uvec4($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2], $0._data[$1/4+3])")
[__readNone]
- uint4 Load4(int location);
+ [ForceInline]
+ __target_intrinsic(hlsl)
+ uint4 Load4(int location)
+ {
+ return __byteAddressBufferLoad<uint4>(this, location);
+ }
[__readNone]
uint4 Load4(int location, out uint status);
@@ -244,11 +279,16 @@ __magic_type(HLSLStructuredBufferType)
__intrinsic_type($(kIROp_HLSLStructuredBufferType))
struct StructuredBuffer
{
- __target_intrinsic(glsl, "$1 = $0._data.length(); $2 = 0")
[__readNone]
+ [__unsafeForceInlineEarly]
void GetDimensions(
out uint numStructs,
- out uint stride);
+ out uint stride)
+ {
+ let rs = __structuredBufferGetDimensions(this);
+ numStructs = rs.x;
+ stride = rs.y;
+ }
__intrinsic_op($(kIROp_StructuredBufferLoad))
__target_intrinsic(glsl, "$0._data[$1]")
@@ -321,34 +361,56 @@ struct $(item.name)
// Note(tfoley): supports all operations from `ByteAddressBuffer`
// TODO(tfoley): can this be made a sub-type?
- __target_intrinsic(glsl, "$1 = $0._data.length() * 4")
- void GetDimensions(
- out uint dim);
+ __target_intrinsic(hlsl)
+ __target_intrinsic(cpp)
+ __target_intrinsic(cuda)
+ [__unsafeForceInlineEarly]
+ void GetDimensions(out uint dim);
- __target_intrinsic(glsl, "$0._data[$1/4]")
+ [__unsafeForceInlineEarly]
+ __specialized_for_target(spirv)
+ __specialized_for_target(glsl)
+ void GetDimensions(out uint dim)
+ {
+ dim = __structuredBufferGetDimensions(__getEquivalentStructuredBuffer<uint>(this)).x*4;
+ }
+
+ __target_intrinsic(hlsl)
[__NoSideEffect]
- uint Load(int location);
+ uint Load(int location)
+ {
+ return __byteAddressBufferLoad<uint>(this, location);
+ }
[__NoSideEffect]
uint Load(int location, out uint status);
- __target_intrinsic(glsl, "uvec2($0._data[$1/4], $0._data[$1/4+1])")
+ __target_intrinsic(hlsl)
[__NoSideEffect]
- uint2 Load2(int location);
+ uint2 Load2(int location)
+ {
+ return __byteAddressBufferLoad<uint2>(this, location);
+ }
[__NoSideEffect]
uint2 Load2(int location, out uint status);
- __target_intrinsic(glsl, "uvec3($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2])")
+ __target_intrinsic(hlsl)
[__NoSideEffect]
- uint3 Load3(int location);
+ uint3 Load3(int location)
+ {
+ return __byteAddressBufferLoad<uint3>(this, location);
+ }
[__NoSideEffect]
uint3 Load3(int location, out uint status);
- __target_intrinsic(glsl, "uvec4($0._data[$1/4], $0._data[$1/4+1], $0._data[$1/4+2], $0._data[$1/4+3])")
+ __target_intrinsic(hlsl)
[__NoSideEffect]
- uint4 Load4(int location);
+ uint4 Load4(int location)
+ {
+ return __byteAddressBufferLoad<uint4>(this, location);
+ }
[__NoSideEffect]
uint4 Load4(int location, out uint status);
@@ -689,25 +751,39 @@ ${{{{
UINT dest,
UINT value);
- __target_intrinsic(glsl, "$0._data[$1/4] = $2")
+ __target_intrinsic(hlsl)
+ [ForceInline]
void Store(
uint address,
- uint value);
+ uint value)
+ {
+ __byteAddressBufferStore(this, address, value);
+ }
- __target_intrinsic(glsl, "$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $2.y")
- void Store2(
- uint address,
- uint2 value);
+ __target_intrinsic(hlsl)
+ [ForceInline]
+ void Store2(uint address, uint2 value)
+ {
+ __byteAddressBufferStore(this, address, value);
+ }
- __target_intrinsic(glsl, "$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $2.y, $0._data[$1/4+2] = $2.z")
+ __target_intrinsic(hlsl)
+ [ForceInline]
void Store3(
uint address,
- uint3 value);
+ uint3 value)
+ {
+ __byteAddressBufferStore(this, address, value);
+ }
- __target_intrinsic(glsl, "$0._data[$1/4] = $2.x, $0._data[$1/4+1] = $2.y, $0._data[$1/4+2] = $2.z, $0._data[$1/4+3] = $2.w")
+ __target_intrinsic(hlsl)
+ [ForceInline]
void Store4(
uint address,
- uint4 value);
+ uint4 value)
+ {
+ __byteAddressBufferStore(this, address, value);
+ }
void Store<T>(int offset, T value)
{
@@ -738,10 +814,17 @@ struct $(item.name)
{
uint DecrementCounter();
- __target_intrinsic(glsl, "$1 = $0._data.length(); $2 = 0")
+ [__readNone]
+ [__unsafeForceInlineEarly]
+ __target_intrinsic(hlsl)
void GetDimensions(
out uint numStructs,
- out uint stride);
+ out uint stride)
+ {
+ let rs = __structuredBufferGetDimensions(this);
+ numStructs = rs.x;
+ stride = rs.y;
+ }
uint IncrementCounter();
@@ -1850,6 +1933,12 @@ __generic<T : __BuiltinFloatingPointType> vector<T,4> dst(vector<T,4> x, vector<
__intrinsic_op($(kIROp_GetEquivalentStructuredBuffer))
RWStructuredBuffer<T> __getEquivalentStructuredBuffer<T>(RWByteAddressBuffer b);
+__intrinsic_op($(kIROp_GetEquivalentStructuredBuffer))
+StructuredBuffer<T> __getEquivalentStructuredBuffer<T>(ByteAddressBuffer b);
+
+__intrinsic_op($(kIROp_GetEquivalentStructuredBuffer))
+RasterizerOrderedStructuredBuffer<T> __getEquivalentStructuredBuffer<T>(RasterizerOrderedByteAddressBuffer b);
+
// Error message
// void errorf( string format, ... );
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index dee8e7197..0b01bdf4e 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -1192,6 +1192,40 @@ const UnownedStringSlice* CPPSourceEmitter::getVectorElementNames(IRVectorType*
return getVectorElementNames(basicType->getBaseType(), elemCount);
}
+bool CPPSourceEmitter::tryEmitInstStmtImpl(IRInst* inst)
+{
+ switch (inst->getOp())
+ {
+ case kIROp_StructuredBufferGetDimensions:
+ {
+ auto count = _generateUniqueName(UnownedStringSlice("_elementCount"));
+ auto stride = _generateUniqueName(UnownedStringSlice("_stride"));
+
+ m_writer->emit("uint ");
+ m_writer->emit(count);
+ m_writer->emit(";\n");
+ m_writer->emit("uint ");
+ m_writer->emit(stride);
+ m_writer->emit(";\n");
+ emitOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), getInfo(EmitOp::Postfix)));
+ m_writer->emit(".GetDimensions(&");
+ m_writer->emit(count);
+ m_writer->emit(", &");
+ m_writer->emit(stride);
+ m_writer->emit(");\n");
+ emitInstResultDecl(inst);
+ m_writer->emit("uint2(");
+ m_writer->emit(count);
+ m_writer->emit(", ");
+ m_writer->emit(stride);
+ m_writer->emit(");\n");
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec)
{
switch (inst->getOp())
diff --git a/source/slang/slang-emit-cpp.h b/source/slang/slang-emit-cpp.h
index 89978e68a..73a0f864e 100644
--- a/source/slang/slang-emit-cpp.h
+++ b/source/slang/slang-emit-cpp.h
@@ -53,6 +53,8 @@ protected:
virtual void _emitType(IRType* type, DeclaratorInfo* declarator) SLANG_OVERRIDE;
virtual void emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount) SLANG_OVERRIDE;
virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE;
+ virtual bool tryEmitInstStmtImpl(IRInst* inst) SLANG_OVERRIDE;
+
virtual void emitPreModuleImpl() SLANG_OVERRIDE;
virtual void emitSimpleValueImpl(IRInst* value) SLANG_OVERRIDE;
virtual void emitSimpleFuncParamImpl(IRParam* param) SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp
index 345aa3168..3e974f60e 100644
--- a/source/slang/slang-emit-cuda.cpp
+++ b/source/slang/slang-emit-cuda.cpp
@@ -449,6 +449,40 @@ void CUDASourceEmitter::emitIntrinsicCallExprImpl(IRCall* inst, IRTargetIntrinsi
Super::emitIntrinsicCallExprImpl(inst, targetIntrinsic, inOuterPrec);
}
+bool CUDASourceEmitter::tryEmitInstStmtImpl(IRInst* inst)
+{
+ switch (inst->getOp())
+ {
+ case kIROp_StructuredBufferGetDimensions:
+ {
+ auto count = _generateUniqueName(UnownedStringSlice("_elementCount"));
+ auto stride = _generateUniqueName(UnownedStringSlice("_stride"));
+
+ m_writer->emit("uint ");
+ m_writer->emit(count);
+ m_writer->emit(";\n");
+ m_writer->emit("uint ");
+ m_writer->emit(stride);
+ m_writer->emit(";\n");
+ emitOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), getInfo(EmitOp::Postfix)));
+ m_writer->emit(".GetDimensions(&");
+ m_writer->emit(count);
+ m_writer->emit(", &");
+ m_writer->emit(stride);
+ m_writer->emit(");\n");
+ emitInstResultDecl(inst);
+ m_writer->emit("make_uint2(");
+ m_writer->emit(count);
+ m_writer->emit(", ");
+ m_writer->emit(stride);
+ m_writer->emit(");\n");
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
bool CUDASourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec)
{
switch(inst->getOp())
diff --git a/source/slang/slang-emit-cuda.h b/source/slang/slang-emit-cuda.h
index b067e0010..a08afd862 100644
--- a/source/slang/slang-emit-cuda.h
+++ b/source/slang/slang-emit-cuda.h
@@ -92,6 +92,7 @@ protected:
virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) SLANG_OVERRIDE;
virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE;
+ virtual bool tryEmitInstStmtImpl(IRInst* inst) SLANG_OVERRIDE;
virtual void emitIntrinsicCallExprImpl(IRCall* inst, IRTargetIntrinsicDecoration* targetIntrinsic, EmitOpInfo const& inOuterPrec) SLANG_OVERRIDE;
virtual void emitModuleImpl(IRModule* module, DiagnosticSink* sink) SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index e1f74f70d..e40a5ceca 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -8,6 +8,7 @@
#include "slang-mangled-lexer.h"
#include "slang-legalize-types.h"
+#include "slang-ir-layout.h"
#include <assert.h>
@@ -2036,6 +2037,22 @@ bool GLSLSourceEmitter::tryEmitInstStmtImpl(IRInst* inst)
m_writer->emit(", -1);\n");
return true;
}
+ case kIROp_StructuredBufferGetDimensions:
+ {
+ emitInstResultDecl(inst);
+ m_writer->emit("uvec2(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ m_writer->emit("._data.length(), ");
+ auto elementType = as<IRHLSLStructuredBufferTypeBase>(inst->getOperand(0)->getDataType())->getElementType();
+ IRIntegerValue stride = 0;
+ if (auto sizeDecor = elementType->findDecoration<IRSizeAndAlignmentDecoration>())
+ {
+ stride = align(sizeDecor->getSize(), (int)sizeDecor->getAlignment());
+ }
+ m_writer->emit(stride);
+ m_writer->emit(");\n");
+ return true;
+ }
default:
return false;
}
diff --git a/source/slang/slang-emit-spirv-ops.h b/source/slang/slang-emit-spirv-ops.h
index d91afad0c..253f90c22 100644
--- a/source/slang/slang-emit-spirv-ops.h
+++ b/source/slang/slang-emit-spirv-ops.h
@@ -1044,6 +1044,20 @@ SpvInst* emitOpCompositeConstruct(
return emitInst(parent, inst, SpvOpCompositeConstruct, idResultType, kResultID, constituents);
}
+// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpCompositeConstruct
+template<typename T, typename T1, typename T2>
+SpvInst* emitOpCompositeConstruct(
+ SpvInstParent* parent,
+ IRInst* inst,
+ const T& idResultType,
+ const T1& constituent1,
+ const T2& constituent2
+)
+{
+ static_assert(isSingular<T>);
+ return emitInst(parent, inst, SpvOpCompositeConstruct, idResultType, kResultID, constituent1, constituent2);
+}
+
// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpCompositeExtract
template<typename T1, typename T2, Index N>
SpvInst* emitOpCompositeExtract(
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 9a7f5ad31..9d8c4d89a 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -1822,6 +1822,8 @@ struct SPIRVEmitContext
return emitStore(parent, as<IRStore>(inst));
case kIROp_RWStructuredBufferGetElementPtr:
return emitStructuredBufferGetElementPtr(parent, inst);
+ case kIROp_StructuredBufferGetDimensions:
+ return emitStructuredBufferGetDimensions(parent, inst);
case kIROp_swizzle:
return emitSwizzle(parent, as<IRSwizzle>(inst));
case kIROp_IntCast:
@@ -2915,6 +2917,21 @@ struct SPIRVEmitContext
return addr;
}
+ SpvInst* emitStructuredBufferGetDimensions(SpvInstParent* parent, IRInst* inst)
+ {
+ IRBuilder builder(inst);
+ auto arrayLength = emitInst(parent, nullptr, SpvOpArrayLength, builder.getUIntType(), kResultID, inst->getOperand(0), SpvLiteralInteger::from32(0));
+ auto elementType = as<IRPtrType>(inst->getOperand(0)->getDataType())->getValueType();
+ IRIntegerValue stride = 0;
+ if (auto sizeDecor = elementType->findDecoration<IRSizeAndAlignmentDecoration>())
+ {
+ stride = align(sizeDecor->getSize(), (int)sizeDecor->getAlignment());
+ }
+ auto strideOperand = emitIntConstant(stride, builder.getUIntType());
+ auto result = emitOpCompositeConstruct(parent, inst, inst->getDataType(), arrayLength, strideOperand);
+ return result;
+ }
+
SpvInst* emitSwizzle(SpvInstParent* parent, IRSwizzle* inst)
{
if (inst->getElementCount() == 1)
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 03d62b540..8ee641acc 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -650,6 +650,8 @@ Result linkAndOptimizeIR(
break;
case CodeGenTarget::GLSL:
+ case CodeGenTarget::SPIRV:
+ case CodeGenTarget::SPIRVAssembly:
// For GLSL targets, we want to translate the vector load/store
// operations into scalar ops. This is in part as a simplification,
// but it also ensures that our generated code respects the lax
@@ -793,6 +795,7 @@ Result linkAndOptimizeIR(
switch (target)
{
case CodeGenTarget::GLSL:
+ case CodeGenTarget::SPIRV:
{
legalizeImageSubscriptForGLSL(irModule);
legalizeConstantBufferLoadForGLSL(irModule);
diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp
index 645662caa..4c5608341 100644
--- a/source/slang/slang-ir-autodiff.cpp
+++ b/source/slang/slang-ir-autodiff.cpp
@@ -709,7 +709,6 @@ IRFunc *DifferentiableTypeConformanceContext::getOrCreateExistentialDAddMethod()
builder.addNameHintDecoration(existentialDAddFunc, UnownedStringSlice("__existential_dadd"));
builder.addBackwardDifferentiableDecoration(existentialDAddFunc);
- this->existentialDAddFunc = existentialDAddFunc;
return existentialDAddFunc;
}
diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp
index 0472e44df..909ffea83 100644
--- a/source/slang/slang-ir-lower-buffer-element-type.cpp
+++ b/source/slang/slang-ir-lower-buffer-element-type.cpp
@@ -500,6 +500,7 @@ namespace Slang
case kIROp_StructuredBufferLoadStatus:
case kIROp_RWStructuredBufferLoad:
case kIROp_RWStructuredBufferLoadStatus:
+ case kIROp_StructuredBufferConsume:
{
IRCloneEnv cloneEnv = {};
builder.setInsertBefore(user);
@@ -512,6 +513,7 @@ namespace Slang
}
case kIROp_Store:
case kIROp_RWStructuredBufferStore:
+ case kIROp_StructuredBufferAppend:
{
// Use must be the dest operand of the store inst.
if (use != user->getOperands() + 0)
@@ -524,6 +526,8 @@ namespace Slang
store->val.set(packedVal);
else if (auto sbStore = as<IRRWStructuredBufferStore>(user))
sbStore->setOperand(2, packedVal);
+ else if (auto sbAppend = as<IRStructuredBufferAppend>(user))
+ sbAppend->setOperand(1, packedVal);
else
SLANG_UNREACHABLE("unhandled store type");
break;
@@ -565,6 +569,8 @@ namespace Slang
case kIROp_RWStructuredBufferGetElementPtr:
ptrValsWorkList.add(user);
break;
+ case kIROp_StructuredBufferGetDimensions:
+ break;
default:
SLANG_UNREACHABLE("unhandled inst of a buffer/pointer value that needs storage lowering.");
break;
diff --git a/tests/compute/byte-address-buffer.slang b/tests/compute/byte-address-buffer.slang
index 9bba63a1f..715be850d 100644
--- a/tests/compute/byte-address-buffer.slang
+++ b/tests/compute/byte-address-buffer.slang
@@ -28,7 +28,7 @@ void test(int val)
uint4 quad = inputBuffer.Load4(int(tmp * 4));
tmp = (quad.x + quad.y + quad.z + quad.w) & 0xF;
- outputBuffer.Store(val * 4, tmp);
+ outputBuffer.Store(val*4, tmp);
}
[numthreads(4, 1, 1)]
diff --git a/tests/compute/unbounded-array-of-array-syntax.slang.glsl b/tests/compute/unbounded-array-of-array-syntax.slang.glsl
index 2ea90e4a6..f426bb55d 100644
--- a/tests/compute/unbounded-array-of-array-syntax.slang.glsl
+++ b/tests/compute/unbounded-array-of-array-syntax.slang.glsl
@@ -1,4 +1,3 @@
-//TEST_IGNORE_FILE:
#version 450
#extension GL_EXT_nonuniform_qualifier : require
layout(row_major) uniform;
@@ -15,9 +14,8 @@ void main()
int index_0 = int(gl_GlobalInvocationID.x);
int innerIndex_0 = index_0 & 3;
int _S1 = nonuniformEXT(index_0 >> 2);
- uint bufferCount_0;
- uint bufferStride_0;
- (bufferCount_0) = (g_aoa_0[_S1])._data.length(); (bufferStride_0) = 0;
+ uvec2 _S2 = uvec2(g_aoa_0[_S1]._data.length(), 0);
+ uint bufferCount_0 = _S2.x;
int innerIndex_1;
if(innerIndex_0 >= int(bufferCount_0))
{
diff --git a/tests/cross-compile/array-of-buffers.slang.glsl b/tests/cross-compile/array-of-buffers.slang.glsl
index fb1a4be2f..53a826a91 100644
--- a/tests/cross-compile/array-of-buffers.slang.glsl
+++ b/tests/cross-compile/array-of-buffers.slang.glsl
@@ -15,7 +15,6 @@ struct S_0
{
vec4 f_0;
};
-
layout(binding = 1)
layout(std140) uniform _S2
{
@@ -27,18 +26,14 @@ layout(std430, binding = 2) readonly buffer StructuredBuffer_S_t_0 {
layout(std430, binding = 3) buffer StructuredBuffer_float4_t_0 {
vec4 _data[];
} sb2_0[5];
-layout(std430, binding = 4) readonly buffer _S3
-{
+layout(std430, binding = 4) readonly buffer StructuredBuffer_uint_t_0 {
uint _data[];
} bb_0[6];
layout(location = 0)
-out vec4 _S4;
+out vec4 _S3;
void main()
{
-
- uint _S5 = ((bb_0[C_0.index_0])._data[(int(C_0.index_0 * 4U))/4]);
- _S4 = cb_0[C_0.index_0].f_0 + sb1_0[C_0.index_0]._data[C_0.index_0].f_0 + sb2_0[C_0.index_0]._data[C_0.index_0] + vec4(float(_S5));
+ _S3 = cb_0[C_0.index_0].f_0 + sb1_0[C_0.index_0]._data[C_0.index_0].f_0 + sb2_0[C_0.index_0]._data[C_0.index_0] + vec4(float(bb_0[C_0.index_0]._data[int(C_0.index_0 * 4U) / 4]));
return;
}
-
diff --git a/tests/cross-compile/array-of-buffers.slang.hlsl b/tests/cross-compile/array-of-buffers.slang.hlsl
index ca4b76bbe..a2c1c6302 100644
--- a/tests/cross-compile/array-of-buffers.slang.hlsl
+++ b/tests/cross-compile/array-of-buffers.slang.hlsl
@@ -13,7 +13,6 @@ cbuffer C_0 : register(b0)
{
SLANG_ParameterGroup_C_0 C_0;
}
-
struct S_0
{
float4 f_0;
@@ -26,9 +25,11 @@ StructuredBuffer<S_0 > sb1_0[int(4)] : register(t0);
RWStructuredBuffer<float4 > sb2_0[int(5)] : register(u0);
ByteAddressBuffer bb_0[int(6)] : register(t4);
-
float4 main() : SV_TARGET
{
- uint _S1 = bb_0[C_0.index_0].Load(int(C_0.index_0 * 4U));
- return cb_0[C_0.index_0].f_0 + sb1_0[C_0.index_0].Load(C_0.index_0).f_0 + sb2_0[C_0.index_0][C_0.index_0] + (float4)float(_S1);
+
+ float4 _S1 = cb_0[C_0.index_0].f_0 + sb1_0[C_0.index_0].Load(C_0.index_0).f_0 + sb2_0[C_0.index_0][C_0.index_0];
+ uint _S2 = bb_0[C_0.index_0].Load(int(C_0.index_0 * 4U));
+ return _S1 + (float4)float(_S2);
}
+
diff --git a/tests/cross-compile/get-dimensions.slang b/tests/cross-compile/get-dimensions.slang
index 65c2a1a70..27cbb18de 100644
--- a/tests/cross-compile/get-dimensions.slang
+++ b/tests/cross-compile/get-dimensions.slang
@@ -10,7 +10,7 @@ struct Thing
float b;
};
-//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer
RWStructuredBuffer<int> outputBuffer;
//TEST_INPUT:ubuffer(data=[7 2 9 53], stride=4):name buffer0
@@ -25,13 +25,16 @@ RWStructuredBuffer<float> buffer2;
//TEST_INPUT:ubuffer(data=[1 0 3 0 7 0], stride=8):name buffer3
RWStructuredBuffer<Thing> buffer3;
-[numthreads(4, 1, 1)]
+//TEST_INPUT:ubuffer(data=[1 0 3 0 7 6], stride=0):name buffer4
+RWByteAddressBuffer buffer4;
+
+[numthreads(5, 1, 1)]
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
{
int index = int(dispatchThreadID.x);
int last = -1;
- uint count, stride;
+ uint count = 0, stride = 0;
if (index == 0)
{
buffer0.GetDimensions(count, stride);
@@ -47,13 +50,17 @@ void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
buffer2.GetDimensions(count, stride);
last = int(buffer2.Load(int(count - 1)));
}
- else
+ else if (index == 3)
{
buffer3.GetDimensions(count, stride);
last = buffer3.Load(int(count - 1)).a;
}
-
+ else
+ {
+ buffer4.GetDimensions(count);
+ last = buffer4.Load(count - 4);
+ }
outputBuffer[index * 2] = int(count);
outputBuffer[index * 2 + 1] = last;
} \ No newline at end of file
diff --git a/tests/cross-compile/get-dimensions.slang.expected.txt b/tests/cross-compile/get-dimensions.slang.expected.txt
index b90b9551c..87709651c 100644
--- a/tests/cross-compile/get-dimensions.slang.expected.txt
+++ b/tests/cross-compile/get-dimensions.slang.expected.txt
@@ -6,3 +6,5 @@
0
3
7
+18
+6
diff --git a/tests/expected-failure.txt b/tests/expected-failure.txt
index effee0e2b..fcfea7c15 100644
--- a/tests/expected-failure.txt
+++ b/tests/expected-failure.txt
@@ -66,7 +66,6 @@ tests/bugs/vec-compare.slang.2 (vk)
tests/bugs/vec-init.slang.2 (vk)
tests/bugs/inlining/global-const-inline.slang.1 (vk)
tests/compute/buffer-layout.slang.2 (vk)
-tests/compute/byte-address-buffer.slang.2 (vk)
tests/compute/dynamic-dispatch-16.slang (vk)
tests/compute/dynamic-dispatch-17.slang (vk)
tests/compute/dynamic-dispatch-18.slang.2 (vk)
@@ -93,9 +92,7 @@ tests/compute/texture-sample-grad-offset-clamp.slang (vk)
tests/compute/texture-simple.slang.4 (vk)
tests/compute/texture-simpler.slang (vk)
tests/compute/vector-scalar-compare.slang.1 (vk)
-tests/cross-compile/get-dimensions.slang.1 (vk)
tests/cross-compile/glsl-bool-ops.slang.1 (vk)
-tests/hlsl/byte-buffer-load-std430.slang (vk)
tests/hlsl/glsl-matrix-layout.slang (vk)
tests/hlsl/packoffset.slang.1 (vk)
tests/hlsl-intrinsic/asfloat16.slang.3 (vk)
@@ -135,7 +132,6 @@ tests/hlsl-intrinsic/active-mask/switch.slang.3 (vk)
tests/hlsl-intrinsic/bit-cast/bit-cast-16-bit.slang.1 (vk)
tests/hlsl-intrinsic/byte-address-buffer/byte-address-16bit-vector.slang.2 (vk)
tests/hlsl-intrinsic/byte-address-buffer/byte-address-16bit.slang.2 (vk)
-tests/hlsl-intrinsic/byte-address-buffer/byte-address-struct.slang.3 (vk)
tests/hlsl-intrinsic/size-of/align-of-3.slang.3 (vk)
tests/hlsl-intrinsic/size-of/size-of-3.slang.3 (vk)
tests/hlsl-intrinsic/wave-mask/wave-active-product.slang.3 (vk)