diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-01-30 16:28:50 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-30 16:28:50 -0500 |
| commit | 5942ff81d9a63ee1e37ba81172ea579646be774e (patch) | |
| tree | 2a4cdb5851348f11a8fcde1605e81c29c1227727 | |
| parent | 415409fc10cfd0d6b2eb805df8f37bdabc4f2405 (diff) | |
Support for 64 bit integer types (#1191)
* * For integer literals add postfix, and use unsigned/signed output appropriately
* Extend GLSL extension handling by type, and for adding 64 bit int extensions
* Added tests for int/uint64 types
* Add explicit Int/UInt64 emit functions to avoid ambiguity.
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 45 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl-extension-tracker.cpp | 33 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl-extension-tracker.h | 6 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 92 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.h | 6 | ||||
| -rw-r--r-- | source/slang/slang-emit-source-writer.cpp | 14 | ||||
| -rw-r--r-- | source/slang/slang-emit-source-writer.h | 4 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/scalar-int64.slang | 21 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/scalar-int64.slang.expected.txt | 4 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/scalar-uint64.slang | 24 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/scalar-uint64.slang.expected.txt | 4 |
11 files changed, 224 insertions, 29 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 48ca6009b..c2bfad0a7 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -743,8 +743,51 @@ void CLikeSourceEmitter::emitSimpleValueImpl(IRInst* inst) switch(inst->op) { case kIROp_IntLit: - m_writer->emit(((IRConstant*) inst)->value.intVal); + { + auto litInst = static_cast<IRConstant*>(inst); + + IRBasicType* type = as<IRBasicType>(inst->getDataType()); + if (type) + { + switch (type->getBaseType()) + { + default: + case BaseType::Int8: + case BaseType::Int16: + case BaseType::Int: + { + m_writer->emit(litInst->value.intVal); + break; + } + case BaseType::UInt8: + case BaseType::UInt16: + case BaseType::UInt: + { + m_writer->emit(UInt(litInst->value.intVal)); + break; + } + case BaseType::Int64: + { + m_writer->emitInt64(int64_t(litInst->value.intVal)); + m_writer->emit("ll"); + break; + } + case BaseType::UInt64: + { + SLANG_COMPILE_TIME_ASSERT(sizeof(litInst->value.intVal) >= sizeof(uint64_t)); + m_writer->emitUInt64(uint64_t(litInst->value.intVal)); + m_writer->emit("ull"); + break; + } + } + } + else + { + // If no type... just output what we have + m_writer->emit(litInst->value.intVal); + } break; + } case kIROp_FloatLit: m_writer->emit(((IRConstant*) inst)->value.floatVal); diff --git a/source/slang/slang-emit-glsl-extension-tracker.cpp b/source/slang/slang-emit-glsl-extension-tracker.cpp index c162f2f46..e1bbb3e46 100644 --- a/source/slang/slang-emit-glsl-extension-tracker.cpp +++ b/source/slang/slang-emit-glsl-extension-tracker.cpp @@ -26,18 +26,35 @@ void GLSLExtensionTracker::requireVersion(ProfileVersion version) } } -void GLSLExtensionTracker::requireHalfExtension() +void GLSLExtensionTracker::requireBaseTypeExtension(BaseType baseType) { - if (!m_hasHalfExtension) + uint32_t bit = 1 << int(baseType); + if (m_hasBaseTypeFlags & bit) { - // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_shader_16bit_storage.txt - requireExtension("GL_EXT_shader_16bit_storage"); - - // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_shader_explicit_arithmetic_types.txt - requireExtension("GL_EXT_shader_explicit_arithmetic_types"); + return; + } - m_hasHalfExtension = true; + switch (baseType) + { + case BaseType::Half: + { + // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_shader_16bit_storage.txt + requireExtension("GL_EXT_shader_16bit_storage"); + + // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_shader_explicit_arithmetic_types.txt + requireExtension("GL_EXT_shader_explicit_arithmetic_types"); + break; + } + case BaseType::UInt64: + case BaseType::Int64: + { + requireExtension("GL_EXT_shader_explicit_arithmetic_types_int64"); + m_hasBaseTypeFlags |= _getFlag(BaseType::UInt64) | _getFlag(BaseType::Int64); + break; + } } + + m_hasBaseTypeFlags |= bit; } diff --git a/source/slang/slang-emit-glsl-extension-tracker.h b/source/slang/slang-emit-glsl-extension-tracker.h index 3ba226fbc..806e430e8 100644 --- a/source/slang/slang-emit-glsl-extension-tracker.h +++ b/source/slang/slang-emit-glsl-extension-tracker.h @@ -15,7 +15,7 @@ public: void requireExtension(const String& name); void requireVersion(ProfileVersion version); - void requireHalfExtension(); + void requireBaseTypeExtension(BaseType baseType); ProfileVersion getRequiredProfileVersion() const { return m_profileVersion; } const StringBuilder& getExtensionRequireLines() const { return m_extensionRequireLines; } @@ -27,7 +27,9 @@ protected: ProfileVersion m_profileVersion = ProfileVersion::GLSL_110; - bool m_hasHalfExtension = false; + static uint32_t _getFlag(BaseType baseType) { return uint32_t(1) << int(baseType); } + + uint32_t m_hasBaseTypeFlags = 0xffffffff & ~(_getFlag(BaseType::UInt64) + _getFlag(BaseType::Int64) + _getFlag(BaseType::Half)); }; } diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 4aae8376c..c319f44e9 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -583,18 +583,29 @@ void GLSLSourceEmitter::_emitGLSLTypePrefix(IRType* type, bool promoteHalfToFloa case kIROp_Int8Type: m_writer->emit("i8"); break; case kIROp_Int16Type: m_writer->emit("i16"); break; case kIROp_IntType: m_writer->emit("i"); break; - case kIROp_Int64Type: m_writer->emit("i64"); break; + case kIROp_Int64Type: + { + _requireBaseType(BaseType::Int64); + m_writer->emit("i64"); + break; + } case kIROp_UInt8Type: m_writer->emit("u8"); break; case kIROp_UInt16Type: m_writer->emit("u16"); break; case kIROp_UIntType: m_writer->emit("u"); break; - case kIROp_UInt64Type: m_writer->emit("u64"); break; + + case kIROp_UInt64Type: + { + _requireBaseType(BaseType::UInt64); + m_writer->emit("u64"); + break; + } case kIROp_BoolType: m_writer->emit("b"); break; case kIROp_HalfType: { - _requireHalf(); + _requireBaseType(BaseType::Half); if (promoteHalfToFloat) { // no prefix @@ -621,9 +632,9 @@ void GLSLSourceEmitter::_emitGLSLTypePrefix(IRType* type, bool promoteHalfToFloa } } -void GLSLSourceEmitter::_requireHalf() +void GLSLSourceEmitter::_requireBaseType(BaseType baseType) { - m_glslExtensionTracker.requireHalfExtension(); + m_glslExtensionTracker.requireBaseTypeExtension(baseType); } void GLSLSourceEmitter::_maybeEmitGLSLFlatModifier(IRType* valueType) @@ -647,6 +658,44 @@ void GLSLSourceEmitter::_maybeEmitGLSLFlatModifier(IRType* valueType) } } +void GLSLSourceEmitter::emitSimpleValueImpl(IRInst* inst) +{ + switch (inst->op) + { + case kIROp_IntLit: + { + auto litInst = static_cast<IRConstant*>(inst); + + IRBasicType* type = as<IRBasicType>(inst->getDataType()); + if (type) + { + switch (type->getBaseType()) + { + default: break; + case BaseType::Int64: + { + m_writer->emitInt64(int64_t(litInst->value.intVal)); + m_writer->emit("l"); + return; + } + case BaseType::UInt64: + { + SLANG_COMPILE_TIME_ASSERT(sizeof(litInst->value.intVal) >= sizeof(uint64_t)); + m_writer->emitUInt64(uint64_t(litInst->value.intVal)); + m_writer->emit("ul"); + return; + } + } + } + break; + } + default: break; + } + + Super::emitSimpleValueImpl(inst); +} + + void GLSLSourceEmitter::emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) { _emitGLSLParameterGroup(varDecl, type); @@ -1317,16 +1366,26 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) { switch (type->op) { - case kIROp_VoidType: - case kIROp_BoolType: - case kIROp_Int8Type: - case kIROp_Int16Type: - case kIROp_IntType: - case kIROp_Int64Type: - case kIROp_UInt8Type: - case kIROp_UInt16Type: - case kIROp_UIntType: - case kIROp_UInt64Type: + case kIROp_Int64Type: + { + _requireBaseType(BaseType::Int64); + m_writer->emit(getDefaultBuiltinTypeName(type->op)); + return; + } + case kIROp_UInt64Type: + { + _requireBaseType(BaseType::UInt64); + m_writer->emit(getDefaultBuiltinTypeName(type->op)); + return; + } + case kIROp_VoidType: + case kIROp_BoolType: + case kIROp_Int8Type: + case kIROp_Int16Type: + case kIROp_IntType: + case kIROp_UInt8Type: + case kIROp_UInt16Type: + case kIROp_UIntType: case kIROp_FloatType: case kIROp_DoubleType: { @@ -1335,11 +1394,10 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) } case kIROp_HalfType: { - _requireHalf(); + _requireBaseType(BaseType::Half); m_writer->emit("float16_t"); return; } - case kIROp_StructType: m_writer->emit(getName(type)); return; diff --git a/source/slang/slang-emit-glsl.h b/source/slang/slang-emit-glsl.h index bbb9c132a..37d4054e9 100644 --- a/source/slang/slang-emit-glsl.h +++ b/source/slang/slang-emit-glsl.h @@ -40,6 +40,9 @@ protected: virtual bool tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* varType) SLANG_OVERRIDE; virtual bool tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec) SLANG_OVERRIDE; + virtual void emitSimpleValueImpl(IRInst* inst) SLANG_OVERRIDE; + + void _emitGLSLTextureOrTextureSamplerType(IRTextureTypeBase* type, char const* baseName); void _emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSLStructuredBufferTypeBase* structuredBufferType); @@ -62,7 +65,8 @@ protected: // of the variable is an integer type. void _maybeEmitGLSLFlatModifier(IRType* valueType); - void _requireHalf(); + void _requireBaseType(BaseType baseType); + void _maybeEmitGLSLCast(IRType* castType, IRInst* inst); }; diff --git a/source/slang/slang-emit-source-writer.cpp b/source/slang/slang-emit-source-writer.cpp index 5661a48bb..8deecc846 100644 --- a/source/slang/slang-emit-source-writer.cpp +++ b/source/slang/slang-emit-source-writer.cpp @@ -197,6 +197,20 @@ void SourceWriter::emit(UInt value) emit(buffer); } +void SourceWriter::emitUInt64(uint64_t value) +{ + char buffer[32]; + sprintf(buffer, "%llu", (unsigned long long)(value)); + emit(buffer); +} + +void SourceWriter::emitInt64(int64_t value) +{ + char buffer[32]; + sprintf(buffer, "%lld", (long long int)value); + emit(buffer); +} + void SourceWriter::emit(int value) { char buffer[16]; diff --git a/source/slang/slang-emit-source-writer.h b/source/slang/slang-emit-source-writer.h index cc9fa1611..dfaf40b31 100644 --- a/source/slang/slang-emit-source-writer.h +++ b/source/slang/slang-emit-source-writer.h @@ -31,6 +31,10 @@ public: void emit(const NameLoc& nameAndLoc); void emit(const StringSliceLoc& nameAndLoc); void emit(IntegerLiteralValue value); + + void emitUInt64(uint64_t value); + void emitInt64(int64_t value); + void emit(UInt value); void emit(int value); void emit(double value); diff --git a/tests/hlsl-intrinsic/scalar-int64.slang b/tests/hlsl-intrinsic/scalar-int64.slang new file mode 100644 index 000000000..4da2a553e --- /dev/null +++ b/tests/hlsl-intrinsic/scalar-int64.slang @@ -0,0 +1,21 @@ +//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute +// No support for int64_t on dx11 +//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute +// No support for int64_t on HLSL +//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 +//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-cuda -compute + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer +RWStructuredBuffer<int> outputBuffer; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint idx = dispatchThreadID.x; + + int64_t v = int64_t(idx) * 0x400010035435435ll; + + outputBuffer[idx] = int(v) ^ int(((v >> 32) & 0xffffffff)); +}
\ No newline at end of file diff --git a/tests/hlsl-intrinsic/scalar-int64.slang.expected.txt b/tests/hlsl-intrinsic/scalar-int64.slang.expected.txt new file mode 100644 index 000000000..c0bb016cd --- /dev/null +++ b/tests/hlsl-intrinsic/scalar-int64.slang.expected.txt @@ -0,0 +1,4 @@ +0 +31435535 +6286AA6A +93C9FF9F diff --git a/tests/hlsl-intrinsic/scalar-uint64.slang b/tests/hlsl-intrinsic/scalar-uint64.slang new file mode 100644 index 000000000..a990ccc22 --- /dev/null +++ b/tests/hlsl-intrinsic/scalar-uint64.slang @@ -0,0 +1,24 @@ +//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute +// No support for uint64_t on DX11 +//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute +// No support for uint64_t on fxc - we need SM6.0 and dxil +// https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/hlsl-shader-model-6-0-features-for-direct3d-12 +//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 +//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile cs_6_3 -use-dxil +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute +//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-cuda -compute + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer +RWStructuredBuffer<int> outputBuffer; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint idx = dispatchThreadID.x; + + uint64_t v = uint64_t(idx) * 0x8000100354354354ull; + // Let's check all the bits make it + v |= 0x8000000000000000ull; + + outputBuffer[idx] = int(v) ^ int(v >> 32); +}
\ No newline at end of file diff --git a/tests/hlsl-intrinsic/scalar-uint64.slang.expected.txt b/tests/hlsl-intrinsic/scalar-uint64.slang.expected.txt new file mode 100644 index 000000000..b8be0469a --- /dev/null +++ b/tests/hlsl-intrinsic/scalar-uint64.slang.expected.txt @@ -0,0 +1,4 @@ +80000000 +D4355357 +286AA6AE +7C9FF9F5 |
