diff options
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 21 | ||||
| -rw-r--r-- | source/slang/slang-ir-util.cpp | 21 | ||||
| -rw-r--r-- | source/slang/slang-ir-util.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 8 | ||||
| -rw-r--r-- | tests/spirv/swizzle-signed-typecast.slang | 26 |
5 files changed, 57 insertions, 21 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index ec9857ecf..8e8e7327b 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -7763,27 +7763,6 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex List<IRInst*>::makeRepeated(scalar, Index(numElems))); } - bool isSignedType(IRType* type) - { - switch (type->getOp()) - { - case kIROp_FloatType: - case kIROp_DoubleType: - return true; - case kIROp_IntType: - case kIROp_Int16Type: - case kIROp_Int64Type: - case kIROp_Int8Type: - return true; - case kIROp_VectorType: - return isSignedType(as<IRVectorType>(type)->getElementType()); - case kIROp_MatrixType: - return isSignedType(as<IRMatrixType>(type)->getElementType()); - default: - return false; - } - } - bool isFloatType(IRInst* type) { switch (type->getOp()) diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp index 13742711c..a2ec15661 100644 --- a/source/slang/slang-ir-util.cpp +++ b/source/slang/slang-ir-util.cpp @@ -2348,4 +2348,25 @@ bool isInstHoistable(IROp op, IRType* type, IRInst* const* fixedArgs) isSpecConstOpHoistable(op, type, fixedArgs); } +bool isSignedType(IRType* type) +{ + switch (type->getOp()) + { + case kIROp_FloatType: + case kIROp_DoubleType: + return true; + case kIROp_IntType: + case kIROp_Int16Type: + case kIROp_Int64Type: + case kIROp_Int8Type: + return true; + case kIROp_VectorType: + return isSignedType(as<IRVectorType>(type)->getElementType()); + case kIROp_MatrixType: + return isSignedType(as<IRMatrixType>(type)->getElementType()); + default: + return false; + } +} + } // namespace Slang diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h index cccec7e05..dccdf5457 100644 --- a/source/slang/slang-ir-util.h +++ b/source/slang/slang-ir-util.h @@ -417,6 +417,8 @@ constexpr bool anyOf(Range&& range, Predicate&& pred) } return false; } + +bool isSignedType(IRType* type); } // namespace Slang #endif diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index a03c75d7d..df3507670 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -7855,6 +7855,14 @@ top: // we simply form a pointer to each of the vector // elements and write to them individually. IRInst* irRightVal = getSimpleVal(context, right); + + // If there is a mismatch between the signedness of the left and rigth values + // then emit a cast + if (isSignedType(swizzleInfo->type) != isSignedType(irRightVal->getDataType())) + { + irRightVal = builder->emitCast(swizzleInfo->type, irRightVal); + } + swizzledStore( loweredBase.val, irRightVal, diff --git a/tests/spirv/swizzle-signed-typecast.slang b/tests/spirv/swizzle-signed-typecast.slang new file mode 100644 index 000000000..459dd3860 --- /dev/null +++ b/tests/spirv/swizzle-signed-typecast.slang @@ -0,0 +1,26 @@ +//TEST:SIMPLE(filecheck=CHECK): -target spirv + +// CHECK: %{{.*}} = OpBitcast %v2uint %{{.*}} + +RWTexture2D<uint3> tex; +void fn(inout int2 origPos, uint offset) +{ + origPos.x += offset; + origPos.y += offset; +} + +uint3 id(float3 coord) +{ + return uint3(coord); +} + +[shader("compute")] +[numthreads(1,1,1)] +void main(uint3 threadId : SV_DispatchThreadID) +{ + uint3 index = id(threadId); + // Passing a uint3 swizzle as a parameter to a function expecting a int2 should result + // in an explicit typecast from unsigned to signed + fn(index.xy, 1); + tex[threadId.xy] = index; +}
\ No newline at end of file |
