diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-03-05 10:59:54 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-05 10:59:54 -0500 |
| commit | 6684d32db1f5693bcfb4971558cb30e855cd3bad (patch) | |
| tree | 480e014b917a6eb0fe72faa6c52a25f4856ed1cb /source | |
| parent | 5951d2a45f3546a619fb5b032a4a422229c46e4c (diff) | |
Feature/glslang spirv version (#1256)
* WIP add support for __spirv_version .
* Added IRRequireSPIRVVersionDecoration
* SPIR-V version passed to glslang.
Enable VK wave tests.
Split ExtensionTracker out, so can be cast and used externally to emit.
Added SourceResult.
* Fix warning on Clang.
* Missing hlsl.meta.h
* Refactor communication/parsing of __spirv_version with glslang.
* Fix some debug typos.
Be more precise in handling of substring handling.
* Make glslang forwards and backwards binary compatible.
* Small comment improvements.
* Added slang-spirv-target-info.h/cpp
* Fix for major/minor on gcc.
* Another fix for gcc/clang.
* VS projects include slang-spirv-target-info.h/cpp
* Removed SPIRVTargetInfo
Added SemanticVersion.
Don't bother with passing a target to glslang. Should be separate from 'version'.
* Renamed slang-emit-glsl-extension-tracker.cpp/.h -> slang-glsl-extension-tracker.cpp/.h
Fixed some VS project issues.
* Fix a comment.
* Added slang-semantic-version.cpp/.h
* Added slang-glsl-extension-tracker.cpp/.h
* Added split that can check for input has all been parsed.
* Fix problem on x86 win build.
Diffstat (limited to 'source')
34 files changed, 1708 insertions, 567 deletions
diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj index fe3d45f1b..636edb46a 100644 --- a/source/core/core.vcxproj +++ b/source/core/core.vcxproj @@ -197,6 +197,7 @@ <ClInclude Include="slang-render-api-util.h" /> <ClInclude Include="slang-riff.h" /> <ClInclude Include="slang-secure-crt.h" /> + <ClInclude Include="slang-semantic-version.h" /> <ClInclude Include="slang-shared-library.h" /> <ClInclude Include="slang-smart-pointer.h" /> <ClInclude Include="slang-std-writers.h" /> @@ -230,6 +231,7 @@ <ClCompile Include="slang-random-generator.cpp" /> <ClCompile Include="slang-render-api-util.cpp" /> <ClCompile Include="slang-riff.cpp" /> + <ClCompile Include="slang-semantic-version.cpp" /> <ClCompile Include="slang-shared-library.cpp" /> <ClCompile Include="slang-std-writers.cpp" /> <ClCompile Include="slang-stream.cpp" /> diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters index aeac70769..49d8a1065 100644 --- a/source/core/core.vcxproj.filters +++ b/source/core/core.vcxproj.filters @@ -90,6 +90,9 @@ <ClInclude Include="slang-secure-crt.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slang-semantic-version.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="slang-shared-library.h"> <Filter>Header Files</Filter> </ClInclude> @@ -185,6 +188,9 @@ <ClCompile Include="slang-riff.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slang-semantic-version.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="slang-shared-library.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/source/core/slang-semantic-version.cpp b/source/core/slang-semantic-version.cpp new file mode 100644 index 000000000..93536e007 --- /dev/null +++ b/source/core/slang-semantic-version.cpp @@ -0,0 +1,50 @@ +// slang-semantic-version.cpp +#include "slang-semantic-version.h" + +#include "../../slang-com-helper.h" + +#include "../core/slang-string-util.h" + +namespace Slang { + +SlangResult SemanticVersion::parse(const UnownedStringSlice& value, SemanticVersion& outVersion) +{ + outVersion.reset(); + + UnownedStringSlice slices[3]; + Index splitCount; + SLANG_RETURN_ON_FAIL(StringUtil::split(value, '.', 3, slices, splitCount)); + if (splitCount <= 0) + { + return SLANG_FAIL; + } + + Int ints[3] = { 0, 0, 0 }; + for (Index i = 0; i < splitCount; i++) + { + SLANG_RETURN_ON_FAIL(StringUtil::parseInt(slices[i], ints[i])); + + const Int max = (i == 0) ? 0x7fffffff : 0xffff; + if (ints[i] < 0 || ints[i] > max) + { + return SLANG_FAIL; + } + } + + outVersion.m_major = uint32_t(ints[0]); + outVersion.m_minor = uint16_t(ints[1]); + outVersion.m_patch = uint16_t(ints[2]); + + return SLANG_OK; +} + +void SemanticVersion::append(StringBuilder& buf) const +{ + buf << Int32(m_major) << "." << Int32(m_minor); + if (m_patch != 0) + { + buf << "." << Int32(m_patch); + } +} + +} // namespace Slang diff --git a/source/core/slang-semantic-version.h b/source/core/slang-semantic-version.h new file mode 100644 index 000000000..bbfcb663e --- /dev/null +++ b/source/core/slang-semantic-version.h @@ -0,0 +1,56 @@ +// slang-semantic-version.h +#ifndef SLANG_SEMANTIC_VERSION_H +#define SLANG_SEMANTIC_VERSION_H + +#include "../core/slang-basic.h" + +namespace Slang +{ + +struct SemanticVersion +{ + typedef SemanticVersion ThisType; + + typedef uint64_t IntegerType; + + SemanticVersion():m_major(0), m_minor(0), m_patch(0) {} + SemanticVersion(int inMajor, int inMinor = 0, int inPatch = 0): + m_major(uint8_t(inMajor)), + m_minor(uint8_t(inMinor)), + m_patch(uint8_t(inPatch)) + {} + + void reset() + { + m_major = 0; + m_minor = 0; + m_patch = 0; + } + + IntegerType toInteger() const { return (IntegerType(m_major) << 32) | (uint32_t(m_minor) << 16) | m_patch; } + void setFromInteger(IntegerType v) + { + m_major = (v >> 32); + m_minor = uint16_t(v >> 16); + m_patch = uint16_t(v); + } + + static SlangResult parse(const UnownedStringSlice& value, SemanticVersion& outVersion); + void append(StringBuilder& buf) const; + + bool operator>(const ThisType& rhs) const { return toInteger() > rhs.toInteger(); } + bool operator>=(const ThisType& rhs) const { return toInteger() >= rhs.toInteger(); } + + bool operator<(const ThisType& rhs) const { return toInteger() < rhs.toInteger(); } + bool operator<=(const ThisType& rhs) const { return toInteger() <= rhs.toInteger(); } + + bool operator==(const ThisType& rhs) const { return toInteger() == rhs.toInteger(); } + bool operator!=(const ThisType& rhs) const { return toInteger() != rhs.toInteger(); } + + uint32_t m_major; + uint16_t m_minor; + uint16_t m_patch; +}; + +} +#endif diff --git a/source/core/slang-string-slice-pool.cpp b/source/core/slang-string-slice-pool.cpp index be7bec785..24187ba5c 100644 --- a/source/core/slang-string-slice-pool.cpp +++ b/source/core/slang-string-slice-pool.cpp @@ -59,6 +59,23 @@ StringSlicePool::Handle StringSlicePool::add(const Slice& slice) return Handle(index); } +bool StringSlicePool::findOrAdd(const Slice& slice, Handle& outHandle) +{ + Handle newHandle = Handle(m_slices.getCount()); + const Handle* handlePtr = m_map.TryGetValueOrAdd(slice, newHandle); + if (handlePtr) + { + outHandle = *handlePtr; + return true; + } + + // Need to add + UnownedStringSlice scopeSlice(m_arena.allocateString(slice.begin(), slice.getLength()), slice.getLength()); + m_slices.add(scopeSlice); + outHandle = newHandle; + return false; +} + StringSlicePool::Handle StringSlicePool::add(StringRepresentation* stringRep) { if (stringRep == nullptr && m_style == Style::Default) diff --git a/source/core/slang-string-slice-pool.h b/source/core/slang-string-slice-pool.h index 2e4b41333..765119360 100644 --- a/source/core/slang-string-slice-pool.h +++ b/source/core/slang-string-slice-pool.h @@ -64,6 +64,9 @@ public: /// Add a string Handle add(const String& string) { return add(string.getUnownedSlice()); } + /// Returns true if found + bool findOrAdd(const Slice& slice, Handle& outHandle); + /// Empty contents void clear(); diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp index 32f017f46..f961e6060 100644 --- a/source/core/slang-string-util.cpp +++ b/source/core/slang-string-util.cpp @@ -30,6 +30,47 @@ namespace Slang { } } +/* static */Index StringUtil::split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices) +{ + Index index = 0; + + const char* start = in.begin(); + const char* end = in.end(); + + while (start < end && index < maxSlices) + { + // Move cur so it's either at the end or at next split character + const char* cur = start; + while (cur < end && *cur != splitChar) + { + cur++; + } + + // Add to output + outSlices[index++] = UnownedStringSlice(start, cur); + + // Skip the split character, if at end we are okay anyway + start = cur + 1; + } + + return index; +} + +/* static */SlangResult StringUtil::split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices, Index& outSlicesCount) +{ + const Index sliceCount = split(in, splitChar, maxSlices, outSlices); + if (sliceCount == maxSlices && sliceCount > 0) + { + // To succeed must have parsed all of the input + if (in.end() != outSlices[sliceCount - 1].end()) + { + return SLANG_FAIL; + } + } + outSlicesCount = sliceCount; + return SLANG_OK; +} + /* static */void StringUtil::join(const List<String>& values, char separator, StringBuilder& out) { join(values, UnownedStringSlice(&separator, 1), out); diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h index 16588bd35..ad25dc9a1 100644 --- a/source/core/slang-string-util.h +++ b/source/core/slang-string-util.h @@ -17,6 +17,11 @@ struct StringUtil /// Slices contents will directly address into in, so contents will only stay valid as long as in does. static void split(const UnownedStringSlice& in, char splitChar, List<UnownedStringSlice>& slicesOut); + /// Splits in into outSlices, up to maxSlices. May not consume all of in (for example if it runs out of space). + static Index split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices); + /// Splits into outSlices up to maxSlices. Returns SLANG_OK if of 'in' consumed. + static SlangResult split(const UnownedStringSlice& in, char splitChar, Index maxSlices, UnownedStringSlice* outSlices, Index& outSlicesCount); + /// Append the joining of in items, separated by 'separator' onto out static void join(const List<String>& in, char separator, StringBuilder& out); static void join(const List<String>& in, const UnownedStringSlice& separator, StringBuilder& out); diff --git a/source/core/slang-string.h b/source/core/slang-string.h index 3fb612af3..10bc76048 100644 --- a/source/core/slang-string.h +++ b/source/core/slang-string.h @@ -93,6 +93,12 @@ namespace Slang return m_end; } + /// True if slice is strictly contained in memory. + bool isMemoryContained(const UnownedStringSlice& slice) const + { + return slice.m_begin >= m_begin && slice.m_end <= m_end; + } + Index getLength() const { return Index(m_end - m_begin); diff --git a/source/slang-glslang/slang-glslang.cpp b/source/slang-glslang/slang-glslang.cpp index 6b2af69b7..4015e00d9 100644 --- a/source/slang-glslang/slang-glslang.cpp +++ b/source/slang-glslang/slang-glslang.cpp @@ -83,19 +83,18 @@ static void dump( } static void dumpDiagnostics( - glslang_CompileRequest* request, + const glslang_CompileRequest_1_1& request, std::string const& log) { - dump(log.c_str(), log.length(), request->diagnosticFunc, request->diagnosticUserData, stderr); + const auto& request_1_0 = request.request_1_0; + dump(log.c_str(), log.length(), request_1_0.diagnosticFunc, request_1_0.diagnosticUserData, stderr); } // Apply the SPIRV-Tools optimizer to generated SPIR-V based on the desired optimization level // TODO: add flag for optimizing SPIR-V size as well -static void glslang_optimizeSPIRV(std::vector<unsigned int>& spirv, unsigned optimizationLevel, unsigned debugInfoType) +static void glslang_optimizeSPIRV(std::vector<unsigned int>& spirv, spv_target_env targetEnv, unsigned optimizationLevel, unsigned debugInfoType) { - spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; - - spvtools::Optimizer optimizer(target_env); + spvtools::Optimizer optimizer(targetEnv); optimizer.SetMessageConsumer( [](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) { auto &out = std::cerr; @@ -202,10 +201,111 @@ static void glslang_optimizeSPIRV(std::vector<unsigned int>& spirv, unsigned opt optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); } -static int glslang_compileGLSLToSPIRV(glslang_CompileRequest* request) + +static glslang::EShTargetLanguageVersion _makeTargetLanguageVersion(int majorVersion, int minorVersion) +{ + return glslang::EShTargetLanguageVersion((uint32_t(majorVersion) << 16) | (uint32_t(minorVersion) << 8)); +} + +static glsl_SPIRVVersion _toSPIRVVersion(glslang::EShTargetLanguageVersion version) +{ + glsl_SPIRVVersion ver; + ver.patch = 0; + ver.major = uint8_t(uint32_t(version) >> 16); + ver.minor = uint8_t(uint32_t(version) >> 8); + return ver; +} + +// For working out the targets based on SPIR-V target strings + +namespace { // anonymous + +struct SPRIVTargetInfo { + const char* name; + spv_target_env targetEnv; +}; + +} // anonymous + +static const SPRIVTargetInfo kSpirvTargetInfos[] = +{ + {"1.0", SPV_ENV_UNIVERSAL_1_0}, + {"vk1.0", SPV_ENV_VULKAN_1_0}, + {"1.1", SPV_ENV_UNIVERSAL_1_1}, + {"cl2.1", SPV_ENV_OPENCL_2_1}, + {"cl2.2", SPV_ENV_OPENCL_2_2}, + {"gl4.0", SPV_ENV_OPENGL_4_0}, + {"gl4.1", SPV_ENV_OPENGL_4_1}, + {"gl4.2", SPV_ENV_OPENGL_4_2}, + {"gl4.3", SPV_ENV_OPENGL_4_3}, + {"gl4.5", SPV_ENV_OPENGL_4_5}, + {"1.2", SPV_ENV_UNIVERSAL_1_2}, + {"cl1.2", SPV_ENV_OPENCL_1_2}, + {"cl_emb1.2", SPV_ENV_OPENCL_EMBEDDED_1_2}, + {"cl2.0", SPV_ENV_OPENCL_2_0}, + {"cl_emb2.0", SPV_ENV_OPENCL_EMBEDDED_2_0}, + {"cl_emb2.1", SPV_ENV_OPENCL_EMBEDDED_2_1}, + {"cl_emb2.2", SPV_ENV_OPENCL_EMBEDDED_2_2}, + {"1.3", SPV_ENV_UNIVERSAL_1_3}, + {"vk1.1", SPV_ENV_VULKAN_1_1}, + {"web_gpu1.0", SPV_ENV_WEBGPU_0}, + {"1.4", SPV_ENV_UNIVERSAL_1_4}, + {"vk1.1_spirv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4}, + {"1.5", SPV_ENV_UNIVERSAL_1_5}, +}; + +static int _findTargetIndex(const char* name) +{ + const int count = int(sizeof(kSpirvTargetInfos) / sizeof(kSpirvTargetInfos[0])); + for (int i = 0; i < count; ++i) + { + const SPRIVTargetInfo& info = kSpirvTargetInfos[i]; + + if (::strcmp(info.name, name) == 0) + { + return i; + } + } + return -1; +} + +static spv_target_env _getUniversalTargetEnv(glslang::EShTargetLanguageVersion inVersion) +{ + glsl_SPIRVVersion spirvVersion = _toSPIRVVersion(inVersion); + uint32_t ver = (uint32_t(spirvVersion.major) << 8) | spirvVersion.minor; + + switch (ver) + { + case 0x100: return SPV_ENV_UNIVERSAL_1_0; + case 0x101: return SPV_ENV_UNIVERSAL_1_1; + case 0x102: return SPV_ENV_UNIVERSAL_1_2; + case 0x103: return SPV_ENV_UNIVERSAL_1_3; + case 0x104: return SPV_ENV_UNIVERSAL_1_4; + case 0x105: return SPV_ENV_UNIVERSAL_1_5; + default: + { + if (ver > 0x105) + { + // This is the highest we known for now..., so try that + return SPV_ENV_UNIVERSAL_1_5; + } + break; + } + } + // Just use the default... + return SPV_ENV_UNIVERSAL_1_2; +} + +static int glslang_compileGLSLToSPIRV(const glslang_CompileRequest_1_1& request) +{ + // Check that the encoding matches + assert(glslang::EShTargetSpv_1_4 == _makeTargetLanguageVersion(1, 4)); + + const auto& request_1_0 = request.request_1_0; + EShLanguage glslangStage; - switch( request->slangStage ) + switch( request_1_0.slangStage ) { #define CASE(SP, GL) case SLANG_STAGE_##SP: glslangStage = EShLang##GL; break CASE(VERTEX, Vertex); @@ -229,16 +329,53 @@ static int glslang_compileGLSLToSPIRV(glslang_CompileRequest* request) return 1; } + + spv_target_env targetEnv = SPV_ENV_UNIVERSAL_1_2; + glslang::EShTargetLanguageVersion targetLanguage = glslang::EShTargetLanguageVersion(0); + + int spirvTargetIndex = -1; + if (request.spirvTargetName) + { + spirvTargetIndex = _findTargetIndex(request.spirvTargetName); + if (spirvTargetIndex < 0) + { + dumpDiagnostics(request, "warning: unknown SPIR-V version\n"); + } + else + { + targetEnv = kSpirvTargetInfos[spirvTargetIndex].targetEnv; + } + } + + // If a version is specified, and no target language is specified, set to universal version of that SPIR-V version + if (request.spirvVersion.major != 0 && targetLanguage == glslang::EShTargetLanguageVersion(0)) + { + targetLanguage = _makeTargetLanguageVersion(request.spirvVersion.major, request.spirvVersion.minor); + } + + // If we don't have a target, but do have a language, use that to determine a universal target + if (spirvTargetIndex < 0 && targetLanguage != glslang::EShTargetLanguageVersion(0)) + { + // We can just use the appropriate universal based on the target language + targetEnv = _getUniversalTargetEnv(targetLanguage); + } + // TODO: compute glslang stage to use glslang::TShader* shader = new glslang::TShader(glslangStage); auto shaderPtr = std::unique_ptr<glslang::TShader>(shader); + // Only set the target language if one is determined + if (targetLanguage != glslang::EShTargetLanguageVersion(0)) + { + shader->setEnvTarget(glslang::EShTargetSpv, targetLanguage); + } + glslang::TProgram* program = new glslang::TProgram(); auto programPtr = std::unique_ptr<glslang::TProgram>(program); - char const* sourceText = (char const*)request->inputBegin; - char const* sourceTextEnd = (char const*)request->inputEnd; + char const* sourceText = (char const*)request_1_0.inputBegin; + char const* sourceTextEnd = (char const*)request_1_0.inputEnd; int sourceTextLength = (int)(sourceTextEnd - sourceText); @@ -247,11 +384,11 @@ static int glslang_compileGLSLToSPIRV(glslang_CompileRequest* request) shader->setStringsWithLengthsAndNames( &sourceText, &sourceTextLength, - &request->sourcePath, + &request_1_0.sourcePath, 1); EShMessages messages = EShMessages(EShMsgSpvRules | EShMsgVulkanRules); - + if( !shader->parse(&gResources, 110, false, messages) ) { dumpDiagnostics(request, shader->getInfoLog()); @@ -283,32 +420,34 @@ static int glslang_compileGLSLToSPIRV(glslang_CompileRequest* request) spv::SpvBuildLogger logger; glslang::GlslangToSpv(*stageIntermediate, spirv, &logger); - if (request->optimizationLevel != SLANG_OPTIMIZATION_LEVEL_NONE) + if (request_1_0.optimizationLevel != SLANG_OPTIMIZATION_LEVEL_NONE) { - glslang_optimizeSPIRV(spirv, request->optimizationLevel, request->debugInfoType); + glslang_optimizeSPIRV(spirv, targetEnv, request_1_0.optimizationLevel, request_1_0.debugInfoType); } dumpDiagnostics(request, logger.getAllMessages()); - dump(spirv.data(), spirv.size() * sizeof(unsigned int), request->outputFunc, request->outputUserData, stdout); + dump(spirv.data(), spirv.size() * sizeof(unsigned int), request_1_0.outputFunc, request_1_0.outputUserData, stdout); } return 0; } -static int glslang_dissassembleSPIRV(glslang_CompileRequest* request) +static int glslang_dissassembleSPIRV(const glslang_CompileRequest_1_1& request) { typedef unsigned int SPIRVWord; - SPIRVWord const* spirvBegin = (SPIRVWord const*)request->inputBegin; - SPIRVWord const* spirvEnd = (SPIRVWord const*)request->inputEnd; + auto& request_1_0 = request.request_1_0; + + SPIRVWord const* spirvBegin = (SPIRVWord const*)request_1_0.inputBegin; + SPIRVWord const* spirvEnd = (SPIRVWord const*)request_1_0.inputEnd; std::vector<SPIRVWord> spirv(spirvBegin, spirvEnd); std::stringstream spirvAsmStream; spv::Disassemble(spirvAsmStream, spirv); std::string result = spirvAsmStream.str(); - dump(result.c_str(), result.length(), request->outputFunc, request->outputUserData, stdout); + dump(result.c_str(), result.length(), request_1_0.outputFunc, request_1_0.outputUserData, stdout); return 0; } @@ -349,13 +488,34 @@ public: bool m_isInitialized = false; }; +static int _compile(const glslang_CompileRequest_1_1& request) +{ + int result = 0; + switch (request.request_1_0.action) + { + default: + result = 1; + break; + + case GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV: + result = glslang_compileGLSLToSPIRV(request); + break; + + case GLSLANG_ACTION_DISSASSEMBLE_SPIRV: + result = glslang_dissassembleSPIRV(request); + break; + } + + return result; +} + extern "C" #ifdef _MSC_VER _declspec(dllexport) #else __attribute__((__visibility__("default"))) #endif -int glslang_compile(glslang_CompileRequest* request) +int glslang_compile_1_1(glslang_CompileRequest_1_1* inRequest) { static ProcessInitializer g_processInitializer; if (!g_processInitializer.init()) @@ -369,21 +529,40 @@ int glslang_compile(glslang_CompileRequest* request) return 1; } - int result = 0; - switch(request->action) + // If it's the right size just use it + if (inRequest->sizeInBytes == sizeof(glslang_CompileRequest_1_1)) { - default: - result = 1; - break; + return _compile(*inRequest); + } + else + { + // NOTE! It could be larger, but here we'll assume thats ok, and copy and use. - case GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV: - result = glslang_compileGLSLToSPIRV(request); - break; + // Try to ensure some binary compatibility, by using sizeInBytes member, and copying - case GLSLANG_ACTION_DISSASSEMBLE_SPIRV: - result = glslang_dissassembleSPIRV(request); - break; + glslang_CompileRequest_1_1 request; + + // Copy into request + const size_t copySize = (inRequest->sizeInBytes > sizeof(request)) ? sizeof(request) : inRequest->sizeInBytes; + ::memcpy(&request, inRequest, copySize); + // Zero any remaining members + memset(((uint8_t*)&request) + copySize, 0, sizeof(request) - copySize); + + return _compile(request); } +} - return result; +extern "C" +#ifdef _MSC_VER +_declspec(dllexport) +#else +__attribute__((__visibility__("default"))) +#endif +int glslang_compile(glslang_CompileRequest_1_0* inRequest) +{ + glslang_CompileRequest_1_1 request; + memset(&request, 0, sizeof(request)); + request.sizeInBytes = sizeof(request); + request.request_1_0 = *inRequest; + return glslang_compile_1_1(&request); } diff --git a/source/slang-glslang/slang-glslang.h b/source/slang-glslang/slang-glslang.h index 16b8fb871..ac59e9bfa 100644 --- a/source/slang-glslang/slang-glslang.h +++ b/source/slang-glslang/slang-glslang.h @@ -12,7 +12,12 @@ enum GLSLANG_ACTION_DISSASSEMBLE_SPIRV, }; -struct glslang_CompileRequest +struct glsl_SPIRVVersion +{ + int major, minor, patch; +}; + +struct glslang_CompileRequest_1_0 { char const* sourcePath; @@ -33,6 +38,18 @@ struct glslang_CompileRequest unsigned debugInfoType; }; -typedef int (*glslang_CompileFunc)(glslang_CompileRequest* request); + +struct glslang_CompileRequest_1_1 +{ + size_t sizeInBytes; ///< Size in bytes of this structure + + glslang_CompileRequest_1_0 request_1_0; + + const char* spirvTargetName; /// A valid TargetName. If null will use universal based on the spirVersion. + glsl_SPIRVVersion spirvVersion; ///< The SPIR-V version. If all are 0 will use the default which is 1.2 currently +}; + +typedef int (*glslang_CompileFunc_1_0)(glslang_CompileRequest_1_0* request); +typedef int (*glslang_CompileFunc_1_1)(glslang_CompileRequest_1_1* request); #endif diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h index 49c968cad..17d7aa0bc 100644 --- a/source/slang/hlsl.meta.slang.h +++ b/source/slang/hlsl.meta.slang.h @@ -374,20 +374,66 @@ SLANG_RAW(" __target_intrinsic(glsl, \"EndPrimitive()\")\n") SLANG_RAW(" void RestartStrip();\n") SLANG_RAW("};\n") SLANG_RAW("\n") -SLANG_RAW("// Note(tfoley): Trying to systematically add all the HLSL builtins\n") +SLANG_RAW("#define VECTOR_MAP_UNARY(TYPE, COUNT, FUNC, VALUE) \\\n") +SLANG_RAW(" vector<TYPE,COUNT> result; for(int i = 0; i < COUNT; ++i) { result[i] = FUNC(VALUE[i]); } return result\n") +SLANG_RAW(" \n") +SLANG_RAW("#define MATRIX_MAP_UNARY(TYPE, ROWS, COLS, FUNC, VALUE) \\\n") +SLANG_RAW(" matrix<TYPE,ROWS,COLS> result; for(int i = 0; i < ROWS; ++i) { result[i] = FUNC(VALUE[i]); } return result\n") +SLANG_RAW("\n") +SLANG_RAW("#define VECTOR_MAP_BINARY(TYPE, COUNT, FUNC, LEFT, RIGHT) \\\n") +SLANG_RAW(" vector<TYPE,COUNT> result; for(int i = 0; i < COUNT; ++i) { result[i] = FUNC(LEFT[i], RIGHT[i]); } return result\n") +SLANG_RAW(" \n") +SLANG_RAW("#define MATRIX_MAP_BINARY(TYPE, ROWS, COLS, FUNC, LEFT, RIGHT) \\\n") +SLANG_RAW(" matrix<TYPE,ROWS,COLS> result; for(int i = 0; i < ROWS; ++i) { result[i] = FUNC(LEFT[i], RIGHT[i]); } return result\n") +SLANG_RAW("\n") +SLANG_RAW("#define VECTOR_MAP_TRINARY(TYPE, COUNT, FUNC, A, B, C) \\\n") +SLANG_RAW(" vector<TYPE,COUNT> result; for(int i = 0; i < COUNT; ++i) { result[i] = FUNC(A[i], B[i], C[i]); } return result\n") +SLANG_RAW(" \n") +SLANG_RAW("#define MATRIX_MAP_TRINARY(TYPE, ROWS, COLS, FUNC, A, B, C) \\\n") +SLANG_RAW(" matrix<TYPE,ROWS,COLS> result; for(int i = 0; i < ROWS; ++i) { result[i] = FUNC(A[i], B[i], C[i]); } return result\n") SLANG_RAW("\n") SLANG_RAW("// Try to terminate the current draw or dispatch call (HLSL SM 4.0)\n") SLANG_RAW("void abort();\n") SLANG_RAW("\n") SLANG_RAW("// Absolute value (HLSL SM 1.0)\n") -SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType> T abs(T x);\n") -SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType, let N : int> vector<T,N> abs(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType, let N : int, let M : int> matrix<T,N,M> abs(matrix<T,N,M> x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType>\n") +SLANG_RAW("T abs(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> abs(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, abs, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> abs(matrix<T,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, abs, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Inverse cosine (HLSL SM 1.0)\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T acos(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> acos(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> acos(matrix<T,N,M> x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T acos(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> acos(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, acos, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> acos(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, acos, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Test if all components are non-zero (HLSL SM 1.0)\n") SLANG_RAW("__generic<T : __BuiltinType> bool all(T x);\n") @@ -411,37 +457,80 @@ SLANG_RAW("__target_intrinsic(glsl, \"bool($0)\")\n") SLANG_RAW("bool any(T x);\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"any(bvec$N0($0))\")\n") -SLANG_RAW("bool any(vector<T,N> x);\n") +SLANG_RAW("bool any(vector<T, N> x);\n") +SLANG_RAW("// TODO: implementation of `any()` in the stdlib is\n") +SLANG_RAW("// blocked on fixing implementation of `bool` vector\n") +SLANG_RAW("// `getAt` on the CUDA codegen path.\n") +SLANG_RAW("/*\n") +SLANG_RAW("{\n") +SLANG_RAW(" bool result = false;\n") +SLANG_RAW(" for(int i = 0; i < N; ++i)\n") +SLANG_RAW(" result = result || any(x[i]);\n") +SLANG_RAW(" return result;\n") +SLANG_RAW("}\n") +SLANG_RAW("*/\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinType, let N : int, let M : int>\n") -SLANG_RAW("// TODO: need to define GLSL mapping\n") -SLANG_RAW("bool any(matrix<T,N,M> x);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("bool any(matrix<T, N, M> x);\n") +SLANG_RAW("/*\n") +SLANG_RAW("{\n") +SLANG_RAW(" bool result = false;\n") +SLANG_RAW(" for(int i = 0; i < N; ++i)\n") +SLANG_RAW(" result = result || any(x[i]);\n") +SLANG_RAW(" return result;\n") +SLANG_RAW("}\n") +SLANG_RAW("*/\n") SLANG_RAW("\n") SLANG_RAW("\n") SLANG_RAW("// Reinterpret bits as a double (HLSL SM 5.0)\n") SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"packDouble2x32(uvec2($0, $1))\")\n") SLANG_RAW("__glsl_extension(GL_ARB_gpu_shader5)\n") SLANG_RAW("double asdouble(uint lowbits, uint highbits);\n") SLANG_RAW("\n") -SLANG_RAW("double asdouble(uint lowbits, uint highbits);\n") -SLANG_RAW("\n") SLANG_RAW("// Reinterpret bits as a float (HLSL SM 4.0)\n") SLANG_RAW("\n") -SLANG_RAW("// GLSL Scalar\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"intBitsToFloat\")\n") SLANG_RAW("float asfloat(int x);\n") +SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"uintBitsToFloat\")\n") SLANG_RAW("float asfloat(uint x);\n") SLANG_RAW("\n") -SLANG_RAW("// GLSL Vector\n") SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"intBitsToFloat\")\n") -SLANG_RAW("vector<float,N> asfloat(vector< int,N> x);\n") +SLANG_RAW("vector<float, N> asfloat(vector< int, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(float, N, asfloat, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"uintBitsToFloat\")\n") -SLANG_RAW("vector<float,N> asfloat(vector<uint,N> x);\n") +SLANG_RAW("vector<float,N> asfloat(vector<uint,N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(float, N, asfloat, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<float,N,M> asfloat(matrix< int,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(float, N, M, asfloat, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<float,N,M> asfloat(matrix<uint,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(float, N, M, asfloat, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// No op\n") SLANG_RAW("__intrinsic_op(") @@ -449,12 +538,14 @@ SLANG_SPLICE(kCompoundIntrinsicOp_Pos ) SLANG_RAW(")\n") SLANG_RAW("float asfloat(float x);\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int>\n") SLANG_RAW("__intrinsic_op(") SLANG_SPLICE(kCompoundIntrinsicOp_Pos ) SLANG_RAW(")\n") SLANG_RAW("vector<float,N> asfloat(vector<float,N> x);\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int, let M : int>\n") SLANG_RAW("__intrinsic_op(") SLANG_SPLICE(kCompoundIntrinsicOp_Pos @@ -462,32 +553,66 @@ SLANG_SPLICE(kCompoundIntrinsicOp_Pos SLANG_RAW(")\n") SLANG_RAW("matrix<float,N,M> asfloat(matrix<float,N,M> x);\n") SLANG_RAW("\n") -SLANG_RAW("// Pass thru to HLSL\n") -SLANG_RAW("float asfloat(uint x);\n") -SLANG_RAW("float asfloat(int x);\n") -SLANG_RAW("__generic<let N : int, let M : int> matrix<float,N,M> asfloat(matrix< int,N,M> x);\n") -SLANG_RAW("__generic<let N : int, let M : int> matrix<float,N,M> asfloat(matrix<uint,N,M> x);\n") -SLANG_RAW("\n") SLANG_RAW("// Inverse sine (HLSL SM 1.0)\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T asin(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> asin(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> asin(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("T asin(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> asin(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T,N,asin,x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> asin(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T,N,M,asin,x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Reinterpret bits as an int (HLSL SM 4.0)\n") SLANG_RAW("\n") -SLANG_RAW("// GLSL scalar\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"floatBitsToInt\")\n") SLANG_RAW("int asint(float x);\n") +SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"int($0)\")\n") SLANG_RAW("int asint(uint x);\n") SLANG_RAW("\n") -SLANG_RAW("// GLSL Vector\n") SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"floatBitsToInt\")\n") -SLANG_RAW("vector<int,N> asint(vector<float,N> x);\n") +SLANG_RAW("vector<int, N> asint(vector<float, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(int, N, asint, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"ivec$N0($0)\")\n") -SLANG_RAW("vector<int,N> asint(vector<uint,N> x);\n") +SLANG_RAW("vector<int, N> asint(vector<uint, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(int, N, asint, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<int, N, M> asint(matrix<float, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(int, N, M, asint, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<int, N, M> asint(matrix<uint, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(int, N, M, asint, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// No op\n") SLANG_RAW("__intrinsic_op(") @@ -495,12 +620,14 @@ SLANG_SPLICE(kCompoundIntrinsicOp_Pos ) SLANG_RAW(")\n") SLANG_RAW("int asint(int x);\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int>\n") SLANG_RAW("__intrinsic_op(") SLANG_SPLICE(kCompoundIntrinsicOp_Pos ) SLANG_RAW(")\n") SLANG_RAW("vector<int,N> asint(vector<int,N> x);\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int, let M : int>\n") SLANG_RAW("__intrinsic_op(") SLANG_SPLICE(kCompoundIntrinsicOp_Pos @@ -508,51 +635,66 @@ SLANG_SPLICE(kCompoundIntrinsicOp_Pos SLANG_RAW(")\n") SLANG_RAW("matrix<int,N,M> asint(matrix<int,N,M> x);\n") SLANG_RAW("\n") -SLANG_RAW("// Pass thru HLSL\n") -SLANG_RAW("\n") -SLANG_RAW("int asint(float x);\n") -SLANG_RAW("int asint(uint x);\n") -SLANG_RAW("\n") -SLANG_RAW("__generic<let N : int> vector<int,N> asint(vector<uint,N> x);\n") -SLANG_RAW("__generic<let N : int, let M : int> matrix<int,N,M> asint(matrix<float,N,M> x);\n") -SLANG_RAW("__generic<let N : int, let M : int> matrix<int,N,M> asint(matrix<uint,N,M> x);\n") -SLANG_RAW("\n") SLANG_RAW("// Reinterpret bits of double as a uint (HLSL SM 5.0)\n") SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"{ uvec2 v = unpackDouble2x32($0); $1 = v.x; $2 = v.y; }\")\n") SLANG_RAW("__glsl_extension(GL_ARB_gpu_shader5)\n") SLANG_RAW("void asuint(double value, out uint lowbits, out uint highbits);\n") SLANG_RAW("\n") -SLANG_RAW("void asuint(double value, out uint lowbits, out uint highbits);\n") -SLANG_RAW("\n") SLANG_RAW("// Reinterpret bits as a uint (HLSL SM 4.0)\n") SLANG_RAW("\n") -SLANG_RAW("// GLSL Scalar\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"floatBitsToUint\")\n") SLANG_RAW("uint asuint(float x);\n") +SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"uint($0)\")\n") SLANG_RAW("uint asuint(int x);\n") SLANG_RAW("\n") -SLANG_RAW("// GLSL Vector\n") SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"floatBitsToUint\")\n") -SLANG_RAW("vector<uint,N> asuint(vector<float,N> x);\n") +SLANG_RAW("vector<uint,N> asuint(vector<float,N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(uint, N, asuint, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"uvec$N0($0)\")\n") -SLANG_RAW("vector<uint,N> asuint(vector<int,N> x);\n") +SLANG_RAW("vector<uint, N> asuint(vector<int, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(uint, N, asuint, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<uint,N,M> asuint(matrix<float,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(uint, N, M, asuint, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<uint, N, M> asuint(matrix<int, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(uint, N, M, asuint, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") -SLANG_RAW("// No op\n") SLANG_RAW("__intrinsic_op(") SLANG_SPLICE(kCompoundIntrinsicOp_Pos ) SLANG_RAW(")\n") SLANG_RAW("uint asuint(uint x);\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int>\n") SLANG_RAW("__intrinsic_op(") SLANG_SPLICE(kCompoundIntrinsicOp_Pos ) SLANG_RAW(")\n") SLANG_RAW("vector<uint,N> asuint(vector<uint,N> x);\n") +SLANG_RAW("\n") SLANG_RAW("__generic<let N : int, let M : int>\n") SLANG_RAW("__intrinsic_op(") SLANG_SPLICE(kCompoundIntrinsicOp_Pos @@ -560,71 +702,180 @@ SLANG_SPLICE(kCompoundIntrinsicOp_Pos SLANG_RAW(")\n") SLANG_RAW("matrix<uint,N,M> asuint(matrix<uint,N,M> x);\n") SLANG_RAW("\n") -SLANG_RAW("// Pass thru HLSL\n") -SLANG_RAW("uint asuint(float x);\n") -SLANG_RAW("uint asuint(int x);\n") -SLANG_RAW("\n") -SLANG_RAW("__generic<let N : int> vector<uint,N> asuint(vector<float,N> x);\n") -SLANG_RAW("__generic<let N : int> vector<uint,N> asuint(vector<int,N> x);\n") +SLANG_RAW("// Inverse tangent (HLSL SM 1.0)\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T atan(T x);\n") SLANG_RAW("\n") -SLANG_RAW("__generic<let N : int, let M : int> matrix<uint,N,M> asuint(matrix<float,N,M> x);\n") -SLANG_RAW("__generic<let N : int, let M : int> matrix<uint,N,M> asuint(matrix<int,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> atan(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, atan, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") -SLANG_RAW("// Inverse tangent (HLSL SM 1.0)\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T atan(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> atan(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> atan(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> atan(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, atan, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl,\"atan($0,$1)\")\n") SLANG_RAW("T atan2(T y, T x);\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl,\"atan($0,$1)\")\n") -SLANG_RAW("vector<T,N> atan2(vector<T,N> y, vector<T,N> x);\n") +SLANG_RAW("vector<T, N> atan2(vector<T, N> y, vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, atan2, y, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") -SLANG_RAW("__target_intrinsic(glsl,\"atan($0,$1)\")\n") -SLANG_RAW("matrix<T,N,M> atan2(matrix<T,N,M> y, matrix<T,N,M> x);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> atan2(matrix<T,N,M> y, matrix<T,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, atan2, y, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Ceiling (HLSL SM 1.0)\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T ceil(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> ceil(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> ceil(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T ceil(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> ceil(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, ceil, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> ceil(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, ceil, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("\n") SLANG_RAW("// Check access status to tiled resource\n") SLANG_RAW("bool CheckAccessFullyMapped(uint status);\n") SLANG_RAW("\n") SLANG_RAW("// Clamp (HLSL SM 1.0)\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType> T clamp(T x, T min, T max);\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int> vector<T,N> clamp(vector<T,N> x, vector<T,N> min, vector<T,N> max);\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int, let M : int> matrix<T,N,M> clamp(matrix<T,N,M> x, matrix<T,N,M> min, matrix<T,N,M> max);\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("T clamp(T x, T minBound, T maxBound)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return min(max(x, minBound), maxBound);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> clamp(vector<T, N> x, vector<T, N> minBound, vector<T, N> maxBound)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return min(max(x, minBound), maxBound);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> clamp(matrix<T,N,M> x, matrix<T,N,M> minBound, matrix<T,N,M> maxBound)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return min(max(x, minBound), maxBound);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Clip (discard) fragment conditionally\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> void clip(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> void clip(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> void clip(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("void clip(T x);\n") +SLANG_RAW("// TODO: filling this in here requires ability to invoke `operator<(T,T)`\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" if(x < T(0)) discard;\n") +SLANG_RAW("}*/\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("void clip(vector<T,N> x);\n") +SLANG_RAW("// TODO: filling this in here requires ability to invoke `operator<(T,T)`\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" if(any(x < T(0))) discard;\n") +SLANG_RAW("}*/\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("void clip(matrix<T,N,M> x);\n") +SLANG_RAW("// TODO: filling this in here requires ability to invoke `operator<(T,T)`\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" if(any(x < T(0))) discard;\n") +SLANG_RAW("}*/\n") SLANG_RAW("\n") SLANG_RAW("// Cosine\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T cos(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> cos(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> cos(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T cos(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> cos(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T,N, cos, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> cos(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, cos, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Hyperbolic cosine\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T cosh(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> cosh(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> cosh(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T cosh(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,N> cosh(vector<T,N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T,N, cosh, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> cosh(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, cosh, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Population count\n") SLANG_RAW("__target_intrinsic(glsl, \"bitCount\")\n") SLANG_RAW("uint countbits(uint value);\n") SLANG_RAW("\n") SLANG_RAW("// Cross product\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType> vector<T,3> cross(vector<T,3> x, vector<T,3> y);\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,3> cross(vector<T,3> left, vector<T,3> right);\n") +SLANG_RAW("// TODO: filling this in here requires ability to invoke `operator*(T,T)`, etc.\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" return vector<T,3>(\n") +SLANG_RAW(" left.y * right.z - left.z * right.y,\n") +SLANG_RAW(" left.z * right.x - left.x * right.z,\n") +SLANG_RAW(" left.x * right.y - left.y * right.x);\n") +SLANG_RAW("}*/\n") +SLANG_RAW("\n") SLANG_RAW("\n") SLANG_RAW("// Convert encoded color\n") -SLANG_RAW("int4 D3DCOLORtoUBYTE4(float4 x);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("int4 D3DCOLORtoUBYTE4(float4 color)\n") +SLANG_RAW("{\n") +SLANG_RAW(" let scaled = color.zyxw * 255.001999f;\n") +SLANG_RAW(" return int4(scaled);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Partial-difference derivatives\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") @@ -713,9 +964,25 @@ SLANG_RAW("matrix<T,N,M> ddy_fine(matrix<T,N,M> x);\n") SLANG_RAW("\n") SLANG_RAW("\n") SLANG_RAW("// Radians to degrees\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T degrees(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> degrees(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> degrees(matrix<T,N,M> x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("T degrees(T x);\n") +SLANG_RAW("// TODO: filling this in here requires ability to invoke `operator*` on T,\n") +SLANG_RAW("// and convert a constant to `T` for the conversion factor\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("vector<T,N> degrees(vector<T,N> x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> degrees(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, degrees, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Matrix determinant\n") SLANG_RAW("\n") @@ -790,14 +1057,44 @@ SLANG_RAW("__target_intrinsic(glsl, \"interpolateAtOffset($0, vec2($1) / 16.0f)\ SLANG_RAW("matrix<T,N,M> EvaluateAttributeSnapped(matrix<T,N,M> x, int2 offset);\n") SLANG_RAW("\n") SLANG_RAW("// Base-e exponent\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T exp(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> exp(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> exp(matrix<T,N,M> x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T exp(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> exp(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, exp, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> exp(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, exp, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Base-2 exponent\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T exp2(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> exp2(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> exp2(matrix<T,N,M> x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T exp2(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,N> exp2(vector<T,N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, exp2, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> exp2(matrix<T,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, exp2, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Convert 16-bit float stored in low bits of integer\n") SLANG_RAW("__target_intrinsic(glsl, \"unpackHalf2x16($0).x\")\n") @@ -816,38 +1113,79 @@ SLANG_RAW("__target_intrinsic(glsl, \"packHalf2x16(vec2($0,0.0))\")\n") SLANG_RAW("vector<uint,N> f32tof16(vector<float,N> value);\n") SLANG_RAW("\n") SLANG_RAW("// Flip surface normal to face forward, if needed\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> faceforward(vector<T,N> n, vector<T,N> i, vector<T,N> ng);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,N> faceforward(vector<T,N> n, vector<T,N> i, vector<T,N> ng);\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" return dot(ng, i) < T(0.0f) ? n : -n;\n") +SLANG_RAW("}*/\n") SLANG_RAW("\n") SLANG_RAW("// Find first set bit starting at high bit and working down\n") SLANG_RAW("__target_intrinsic(glsl,\"findMSB\")\n") SLANG_RAW("int firstbithigh(int value);\n") SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl,\"findMSB\")\n") -SLANG_RAW("__generic<let N : int> vector<int,N> firstbithigh(vector<int,N> value);\n") +SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("vector<int, N> firstbithigh(vector<int, N> value)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(int, N, firstbithigh, value);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__target_intrinsic(glsl,\"findMSB\")\n") SLANG_RAW("uint firstbithigh(uint value);\n") SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl,\"findMSB\")\n") -SLANG_RAW("__generic<let N : int> vector<uint,N> firstbithigh(vector<uint,N> value);\n") +SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("vector<uint,N> firstbithigh(vector<uint,N> value)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(uint, N, firstbithigh, value);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Find first set bit starting at low bit and working up\n") SLANG_RAW("__target_intrinsic(glsl,\"findLSB\")\n") SLANG_RAW("int firstbitlow(int value);\n") SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl,\"findLSB\")\n") -SLANG_RAW("__generic<let N : int> vector<int,N> firstbitlow(vector<int,N> value);\n") +SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("vector<int,N> firstbitlow(vector<int,N> value)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(int, N, firstbitlow, value);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__target_intrinsic(glsl,\"findLSB\")\n") SLANG_RAW("uint firstbitlow(uint value);\n") SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl,\"findLSB\")\n") -SLANG_RAW("__generic<let N : int> vector<uint,N> firstbitlow(vector<uint,N> value);\n") +SLANG_RAW("__generic<let N : int>\n") +SLANG_RAW("vector<uint,N> firstbitlow(vector<uint,N> value)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(uint, N, firstbitlow, value);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Floor (HLSL SM 1.0)\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T floor(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> floor(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> floor(matrix<T,N,M> x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T floor(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> floor(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, floor, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> floor(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, floor, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Fused multiply-add for doubles\n") SLANG_RAW("double fma(double a, double b, double c);\n") @@ -855,9 +1193,23 @@ SLANG_RAW("__generic<let N : int> vector<double, N> fma(vector<double, N> a, vec SLANG_RAW("__generic<let N : int, let M : int> matrix<double,N,M> fma(matrix<double,N,M> a, matrix<double,N,M> b, matrix<double,N,M> c);\n") SLANG_RAW("\n") SLANG_RAW("// Floating point remainder of x/y\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T fmod(T x, T y);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> fmod(vector<T,N> x, vector<T,N> y);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> fmod(matrix<T,N,M> x, matrix<T,N,M> y);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T fmod(T x, T y);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> fmod(vector<T, N> x, vector<T, N> y)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, fmod, x, y);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> fmod(matrix<T, N, M> x, matrix<T, N, M> y)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, fmod, x, y);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Fractional part\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") @@ -865,22 +1217,58 @@ SLANG_RAW("__target_intrinsic(glsl, fract)\n") SLANG_RAW("T frac(T x);\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, fract)\n") -SLANG_RAW("vector<T,N> frac(vector<T,N> x);\n") +SLANG_RAW("vector<T, N> frac(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, frac, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") -SLANG_RAW("__target_intrinsic(glsl, fract)\n") -SLANG_RAW("matrix<T,N,M> frac(matrix<T,N,M> x);\n") +SLANG_RAW("matrix<T, N, M> frac(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, frac, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Split float into mantissa and exponent\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T frexp(T x, out T exp);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> frexp(vector<T,N> x, out vector<T,N> exp);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> frexp(matrix<T,N,M> x, out matrix<T,N,M> exp);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("T frexp(T x, out T exp);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> frexp(vector<T, N> x, out vector<T, N> exp)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, frexp, x, exp);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> frexp(matrix<T, N, M> x, out matrix<T, N, M> exp)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, frexp, x, exp);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Texture filter width\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T fwidth(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> fwidth(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> fwidth(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T fwidth(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> fwidth(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, fwidth, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> fwidth(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, fwidth, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Get number of samples in render target\n") SLANG_RAW("uint GetRenderTargetSampleCount();\n") @@ -1023,80 +1411,187 @@ SLANG_RAW("\n") SLANG_RAW("// Is floating-point value finite?\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") -SLANG_RAW("__target_intrinsic(glsl, \"(!(isinf($0) || isnan($0)))\")\n") -SLANG_RAW("bool isfinite(T x);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(cpu)\n") +SLANG_RAW("__target_intrinsic(cuda)\n") +SLANG_RAW("//__target_intrinsic(glsl, \"(!(isinf($0) || isnan($0)))\")\n") +SLANG_RAW("bool isfinite(T x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return !(isinf(x) || isnan(x));\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") -SLANG_RAW("__target_intrinsic(glsl, \"(!(isinf($0) || isnan($0)))\")\n") -SLANG_RAW("vector<bool,N> isfinite(vector<T,N> x);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("//__target_intrinsic(glsl, \"(!(isinf($0) || isnan($0)))\")\n") +SLANG_RAW("vector<bool, N> isfinite(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(bool, N, isfinite, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") -SLANG_RAW("matrix<bool,N,M> isfinite(matrix<T,N,M> x);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<bool, N, M> isfinite(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(bool, N, M, isfinite, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Is floating-point value infinite?\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> bool isinf(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<bool,N> isinf(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<bool,N,M> isinf(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("bool isinf(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<bool, N> isinf(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(bool, N, isinf, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<bool, N, M> isinf(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(bool, N, M, isinf, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Is floating-point value not-a-number?\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> bool isnan(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<bool,N> isnan(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<bool,N,M> isnan(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("bool isnan(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<bool, N> isnan(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(bool, N, isnan, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<bool, N, M> isnan(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(bool, N, M, isnan, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Construct float from mantissa and exponent\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"($0 * pow(2.0f, $1))\")\n") SLANG_RAW("T ldexp(T x, T exp);\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" return x * exp2(exp);\n") +SLANG_RAW("}*/\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"($0 * pow(2.0f, $1))\")\n") -SLANG_RAW("vector<T,N> ldexp(vector<T,N> x, vector<T,N> exp);\n") +SLANG_RAW("vector<T, N> ldexp(vector<T, N> x, vector<T, N> exp)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, ldexp, x, exp);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") -SLANG_RAW("matrix<T,N,M> ldexp(matrix<T,N,M> x, matrix<T,N,M> exp);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> ldexp(matrix<T, N, M> x, matrix<T, N, M> exp)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, ldexp, x, exp);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Vector length\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> T length(vector<T,N> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("T length(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return sqrt(dot(x, x));\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Linear interpolation\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, mix)\n") SLANG_RAW("T lerp(T x, T y, T s);\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" return x * (1 - s) + y * s;\n") +SLANG_RAW("}*/\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, mix)\n") -SLANG_RAW("vector<T,N> lerp(vector<T,N> x, vector<T,N> y, vector<T,N> s);\n") +SLANG_RAW("vector<T, N> lerp(vector<T, N> x, vector<T, N> y, vector<T, N> s)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_TRINARY(T, N, lerp, x, y, s);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") -SLANG_RAW("__target_intrinsic(glsl, mix)\n") -SLANG_RAW("matrix<T,N,M> lerp(matrix<T,N,M> x, matrix<T,N,M> y, matrix<T,N,M> s);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> lerp(matrix<T,N,M> x, matrix<T,N,M> y, matrix<T,N,M> s)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_TRINARY(T, N, M, lerp, x, y, s);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Legacy lighting function (obsolete)\n") SLANG_RAW("float4 lit(float n_dot_l, float n_dot_h, float m);\n") SLANG_RAW("\n") SLANG_RAW("// Base-e logarithm\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T log(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> log(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> log(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T log(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> log(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, log, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> log(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, log, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Base-10 logarithm\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType> \n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"(log( $0 ) * $S0( 0.43429448190325182765112891891661) )\" )\n") SLANG_RAW("T log10(T x);\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"(log( $0 ) * $S0(0.43429448190325182765112891891661) )\" )\n") -SLANG_RAW("vector<T,N> log10(vector<T,N> x);\n") +SLANG_RAW("vector<T,N> log10(vector<T,N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, log10, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> \n") -SLANG_RAW("__target_intrinsic(glsl, \"(log( $0 ) * $S0(0.43429448190325182765112891891661) )\" )\n") -SLANG_RAW("matrix<T,N,M> log10(matrix<T,N,M> x);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> log10(matrix<T,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, log10, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Base-2 logarithm\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T log2(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> log2(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> log2(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T log2(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,N> log2(vector<T,N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, log2, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> log2(matrix<T,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, log2, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// multiply-add\n") SLANG_RAW("\n") @@ -1110,19 +1605,65 @@ SLANG_RAW("__target_intrinsic(glsl, fma)\n") SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int, let M : int> matrix<T,N,M> mad(matrix<T,N,M> mvalue, matrix<T,N,M> avalue, matrix<T,N,M> bvalue);\n") SLANG_RAW("\n") SLANG_RAW("// maximum\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType> T max(T x, T y);\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int> vector<T,N> max(vector<T,N> x, vector<T,N> y);\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int, let M : int> matrix<T,N,M> max(matrix<T,N,M> x, matrix<T,N,M> y);\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType>\n") +SLANG_RAW("T max(T x, T y);\n") +SLANG_RAW("// Note: a stdlib implementation of `max` (or `min`) will require splitting\n") +SLANG_RAW("// floating-point and integer cases apart, because the floating-point\n") +SLANG_RAW("// version needs to correctly handle the case where one of the inputs\n") +SLANG_RAW("// is not-a-number.\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> max(vector<T, N> x, vector<T, N> y)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, max, x, y);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> max(matrix<T, N, M> x, matrix<T, N, M> y)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, max, x, y);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// minimum\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType> T min(T x, T y);\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int> vector<T,N> min(vector<T,N> x, vector<T,N> y);\n") -SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int, let M : int> matrix<T,N,M> min(matrix<T,N,M> x, matrix<T,N,M> y);\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType>\n") +SLANG_RAW("T min(T x, T y);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,N> min(vector<T,N> x, vector<T,N> y)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, min, x, y);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinArithmeticType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> min(matrix<T,N,M> x, matrix<T,N,M> y)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, min, x, y);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// split into integer and fractional parts (both with same sign)\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T modf(T x, out T ip);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> modf(vector<T,N> x, out vector<T,N> ip);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> modf(matrix<T,N,M> x, out matrix<T,N,M> ip);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T modf(T x, out T ip);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,N> modf(vector<T,N> x, out vector<T,N> ip)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, modf, x, ip);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> modf(matrix<T,N,M> x, out matrix<T,N,M> ip)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, modf, x, ip);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// msad4 (whatever that is)\n") SLANG_RAW("uint4 msad4(uint reference, uint2 source, uint4 accum);\n") @@ -1153,8 +1694,16 @@ SLANG_RAW("// matrix-matrix\n") SLANG_RAW("__generic<T : __BuiltinArithmeticType, let R : int, let N : int, let C : int> __intrinsic_op(mulMatrixMatrix) matrix<T,R,C> mul(matrix<T,R,N> x, matrix<T,N,C> y);\n") SLANG_RAW("\n") SLANG_RAW("// noise (deprecated)\n") -SLANG_RAW("float noise(float x);\n") -SLANG_RAW("__generic<let N : int> float noise(vector<float, N> x);\n") +SLANG_RAW("\n") +SLANG_RAW("float noise(float x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return 0;\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<let N : int> float noise(vector<float, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return 0;\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("/// Indicate that an index may be non-uniform at execution time.\n") SLANG_RAW("///\n") @@ -1174,23 +1723,48 @@ SLANG_RAW("/// Note: a future version of Slang may take responsibility for inser SLANG_RAW("/// to this function as necessary in output code, rather than make this\n") SLANG_RAW("/// the user's responsibility, so that the default behavior of the language\n") SLANG_RAW("/// is more semantically \"correct.\"\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, nonuniformEXT)\n") SLANG_RAW("__glsl_extension(GL_EXT_nonuniform_qualifier)\n") SLANG_RAW("[__readNone]\n") -SLANG_RAW("uint NonUniformResourceIndex(uint index);\n") +SLANG_RAW("uint NonUniformResourceIndex(uint index)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return index;\n") +SLANG_RAW("}\n") SLANG_RAW("\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, nonuniformEXT)\n") SLANG_RAW("__glsl_extension(GL_EXT_nonuniform_qualifier)\n") SLANG_RAW("[__readNone]\n") -SLANG_RAW("int NonUniformResourceIndex(int index);\n") +SLANG_RAW("int NonUniformResourceIndex(int index)\n") +SLANG_RAW("{\n") +SLANG_RAW(" return index;\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Normalize a vector\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> normalize(vector<T,N> x);\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" return x / length(x);\n") +SLANG_RAW("}*/\n") SLANG_RAW("\n") SLANG_RAW("// Raise to a power\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T pow(T x, T y);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> pow(vector<T,N> x, vector<T,N> y);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> pow(matrix<T,N,M> x, matrix<T,N,M> y);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T pow(T x, T y);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> pow(vector<T, N> x, vector<T, N> y)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, pow, x, y);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> pow(matrix<T,N,M> x, matrix<T,N,M> y)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, pow, x, y);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Output message\n") SLANG_RAW("\n") @@ -1268,26 +1842,66 @@ SLANG_RAW(" out float RoundedInsideTessFactors,\n") SLANG_RAW(" out float UnroundedInsideTessFactors);\n") SLANG_RAW("\n") SLANG_RAW("// Degrees to radians\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T radians(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> radians(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> radians(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("T radians(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> radians(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, radians, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> radians(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, radians, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Approximate reciprocal\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"1.0/($0)\")\n") SLANG_RAW("T rcp(T x);\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" return T(1) / x;\n") +SLANG_RAW("}*/\n") SLANG_RAW("\n") -SLANG_RAW("// TODO: vector and matrix approx. reciprocals needto be deconstructed for GLSL\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> rcp(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> rcp(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("vector<T, N> rcp(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, rcp, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("// Note: GLSL doesn't define a vector `rcp`, so not intrinsic there\n") +SLANG_RAW("matrix<T, N, M> rcp(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, rcp, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Reflect incident vector across plane with given normal\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") SLANG_RAW("vector<T,N> reflect(vector<T,N> i, vector<T,N> n);\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" return i - T(2) * dot(n,i) * n;\n") +SLANG_RAW("}*/\n") SLANG_RAW("\n") SLANG_RAW("// Refract incident vector given surface normal and index of refraction\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") SLANG_RAW("vector<T,N> refract(vector<T,N> i, vector<T,N> n, float eta);\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" let dotNI = dot(n,i);\n") +SLANG_RAW(" let k = T(1) - eta*eta*(T(1) - dotNI * dotNI);\n") +SLANG_RAW(" if(k < 0) return vector<T,N>(T(0));\n") +SLANG_RAW(" return eta * i - (eta * dotNI + sqrt(k)) * n;\n") +SLANG_RAW("}*/\n") SLANG_RAW("\n") SLANG_RAW("// Reverse order of bits\n") SLANG_RAW("__target_intrinsic(glsl, \"bitfieldReverse\")\n") @@ -1297,45 +1911,56 @@ SLANG_RAW("__target_intrinsic(glsl, \"bitfieldReverse\")\n") SLANG_RAW("__generic<let N : int> vector<uint,N> reversebits(vector<uint,N> value);\n") SLANG_RAW("\n") SLANG_RAW("// Round-to-nearest\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T round(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> round(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> round(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T round(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> round(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, round, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> round(matrix<T,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, round, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Reciprocal of square root\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"inversesqrt($0)\")\n") SLANG_RAW("T rsqrt(T x);\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"inversesqrt($0)\")\n") -SLANG_RAW("vector<T,N> rsqrt(vector<T,N> x);\n") +SLANG_RAW("vector<T, N> rsqrt(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, rsqrt, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") -SLANG_RAW("__target_intrinsic(glsl, \"inversesqrt($0)\")\n") -SLANG_RAW("matrix<T,N,M> rsqrt(matrix<T,N,M> x);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> rsqrt(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, rsqrt, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Clamp value to [0,1] range\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") -SLANG_RAW("__target_intrinsic(glsl, \"clamp($0, 0, 1)\")\n") -SLANG_RAW("T saturate(T x);\n") -SLANG_RAW("\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") -SLANG_RAW("__target_intrinsic(glsl, \"clamp($0, 0, 1)\")\n") -SLANG_RAW("vector<T,N> saturate(vector<T,N> x);\n") -SLANG_RAW("\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") -SLANG_RAW("__target_intrinsic(glsl, \"clamp($0, 0, 1)\")\n") -SLANG_RAW("matrix<T,N,M> saturate(matrix<T,N,M> x);\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") -SLANG_RAW("__specialized_for_target(glsl)\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("T saturate(T x)\n") SLANG_RAW("{\n") SLANG_RAW(" return clamp<T>(x, T(0), T(1));\n") SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") -SLANG_RAW("__specialized_for_target(glsl)\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("vector<T,N> saturate(vector<T,N> x)\n") SLANG_RAW("{\n") SLANG_RAW(" return clamp<T,N>(x,\n") @@ -1343,115 +1968,229 @@ SLANG_RAW(" vector<T,N>(T(0)),\n") SLANG_RAW(" vector<T,N>(T(1)));\n") SLANG_RAW("}\n") SLANG_RAW("\n") -SLANG_RAW("// HACK: need a helper to turn a scalar into a matrix,\n") -SLANG_RAW("// because GLSL and HLSL disagree on the semantics of\n") -SLANG_RAW("// constructing a matrix from a single scalar.\n") -SLANG_RAW("__generic<T, let N : int, let M : int>\n") -SLANG_RAW("matrix<T,N,M> __scalarToMatrix(T value);\n") -SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") -SLANG_RAW("__specialized_for_target(glsl)\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("matrix<T,N,M> saturate(matrix<T,N,M> x)\n") SLANG_RAW("{\n") -SLANG_RAW(" return clamp<T,N,M>(x,\n") -SLANG_RAW(" __scalarToMatrix<T,N,M>(T(0)),\n") -SLANG_RAW(" __scalarToMatrix<T,N,M>(T(1)));\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, saturate, x);\n") SLANG_RAW("}\n") SLANG_RAW("\n") -SLANG_RAW("\n") SLANG_RAW("// Extract sign of value\n") SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType>\n") SLANG_RAW("__target_intrinsic(glsl, \"int(sign($0))\")\n") SLANG_RAW("int sign(T x);\n") SLANG_RAW("\n") SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") SLANG_RAW("__target_intrinsic(glsl, \"ivec$N0(sign($0))\")\n") -SLANG_RAW("vector<int,N> sign(vector<T,N> x);\n") +SLANG_RAW("vector<int, N> sign(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(int, N, sign, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") -SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType, let N : int, let M : int> matrix<int,N,M> sign(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinSignedArithmeticType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<int, N, M> sign(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(int, N, M, sign, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("\n") SLANG_RAW("// Sine\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T sin(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> sin(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> sin(matrix<T,N,M> x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T sin(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> sin(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, sin, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> sin(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, sin, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Sine and cosine\n") SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") -SLANG_RAW("__target_intrinsic(glsl, \"$1 = sin($0); $2 = cos($0);\")\n") -SLANG_RAW("void sincos(T x, out T s, out T c);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> void sincos(vector<T,N> x, out vector<T,N> s, out vector<T,N> c);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> void sincos(matrix<T,N,M> x, out matrix<T,N,M> s, out matrix<T,N,M> c);\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("void sincos(T x, out T s, out T c)\n") +SLANG_RAW("{\n") +SLANG_RAW(" s = sin(x);\n") +SLANG_RAW(" c = cos(x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("void sincos(vector<T,N> x, out vector<T,N> s, out vector<T,N> c)\n") +SLANG_RAW("{\n") +SLANG_RAW(" s = sin(x);\n") +SLANG_RAW(" c = cos(x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("void sincos(matrix<T,N,M> x, out matrix<T,N,M> s, out matrix<T,N,M> c)\n") +SLANG_RAW("{\n") +SLANG_RAW(" s = sin(x);\n") +SLANG_RAW(" c = cos(x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Hyperbolic Sine\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T sinh(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> sinh(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> sinh(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T sinh(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> sinh(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, sinh, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> sinh(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, sinh, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Smooth step (Hermite interpolation)\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T smoothstep(T min, T max, T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> smoothstep(vector<T,N> min, vector<T,N> max, vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> smoothstep(matrix<T,N,M> min, matrix<T,N,M> max, matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T smoothstep(T min, T max, T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> smoothstep(vector<T, N> min, vector<T, N> max, vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_TRINARY(T, N, smoothstep, min, max, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> smoothstep(matrix<T, N, M> min, matrix<T, N, M> max, matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_TRINARY(T, N, M, smoothstep, min, max, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Square root\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T sqrt(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> sqrt(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> sqrt(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T sqrt(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> sqrt(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, sqrt, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> sqrt(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, sqrt, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Step function\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T step(T y, T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> step(vector<T,N> y, vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> step(matrix<T,N,M> y, matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("T step(T y, T x);\n") +SLANG_RAW("/*{\n") +SLANG_RAW(" return x < y ? T(0.0f) : T(1.0f);\n") +SLANG_RAW("}*/\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,N> step(vector<T,N> y, vector<T,N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_BINARY(T, N, step, y, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> step(matrix<T, N, M> y, matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_BINARY(T, N, M, step, y, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Tangent\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T tan(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> tan(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> tan(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T tan(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> tan(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, tan, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> tan(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, tan, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Hyperbolic tangent\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T tanh(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> tanh(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> tanh(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T tanh(T x);\n") SLANG_RAW("\n") -SLANG_RAW("// Legacy texture-fetch operations\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T,N> tanh(vector<T,N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, tanh, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") -SLANG_RAW("/*\n") -SLANG_RAW("float4 tex1D(sampler1D s, float t);\n") -SLANG_RAW("float4 tex1D(sampler1D s, float t, float ddx, float ddy);\n") -SLANG_RAW("float4 tex1Dbias(sampler1D s, float4 t);\n") -SLANG_RAW("float4 tex1Dgrad(sampler1D s, float t, float ddx, float ddy);\n") -SLANG_RAW("float4 tex1Dlod(sampler1D s, float4 t);\n") -SLANG_RAW("float4 tex1Dproj(sampler1D s, float4 t);\n") -SLANG_RAW("\n") -SLANG_RAW("float4 tex2D(sampler2D s, float2 t);\n") -SLANG_RAW("float4 tex2D(sampler2D s, float2 t, float2 ddx, float2 ddy);\n") -SLANG_RAW("float4 tex2Dbias(sampler2D s, float4 t);\n") -SLANG_RAW("float4 tex2Dgrad(sampler2D s, float2 t, float2 ddx, float2 ddy);\n") -SLANG_RAW("float4 tex2Dlod(sampler2D s, float4 t);\n") -SLANG_RAW("float4 tex2Dproj(sampler2D s, float4 t);\n") -SLANG_RAW("\n") -SLANG_RAW("float4 tex3D(sampler3D s, float3 t);\n") -SLANG_RAW("float4 tex3D(sampler3D s, float3 t, float3 ddx, float3 ddy);\n") -SLANG_RAW("float4 tex3Dbias(sampler3D s, float4 t);\n") -SLANG_RAW("float4 tex3Dgrad(sampler3D s, float3 t, float3 ddx, float3 ddy);\n") -SLANG_RAW("float4 tex3Dlod(sampler3D s, float4 t);\n") -SLANG_RAW("float4 tex3Dproj(sampler3D s, float4 t);\n") -SLANG_RAW("\n") -SLANG_RAW("float4 texCUBE(samplerCUBE s, float3 t);\n") -SLANG_RAW("float4 texCUBE(samplerCUBE s, float3 t, float3 ddx, float3 ddy);\n") -SLANG_RAW("float4 texCUBEbias(samplerCUBE s, float4 t);\n") -SLANG_RAW("float4 texCUBEgrad(samplerCUBE s, float3 t, float3 ddx, float3 ddy);\n") -SLANG_RAW("float4 texCUBElod(samplerCUBE s, float4 t);\n") -SLANG_RAW("float4 texCUBEproj(samplerCUBE s, float4 t);\n") -SLANG_RAW("*/\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T,N,M> tanh(matrix<T,N,M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, tanh, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Matrix transpose\n") -SLANG_RAW("__generic<T : __BuiltinType, let N : int, let M : int> matrix<T,M,N> transpose(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("matrix<T, M, N> transpose(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" matrix<T,M,N> result;\n") +SLANG_RAW(" for(int r = 0; r < M; ++r)\n") +SLANG_RAW(" for(int c = 0; c < N; ++c)\n") +SLANG_RAW(" result[r][c] = x[c][r];\n") +SLANG_RAW(" return result;\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Truncate to integer\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType> T trunc(T x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int> vector<T,N> trunc(vector<T,N> x);\n") -SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int> matrix<T,N,M> trunc(matrix<T,N,M> x);\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType>\n") +SLANG_RAW("T trunc(T x);\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("__target_intrinsic(glsl)\n") +SLANG_RAW("vector<T, N> trunc(vector<T, N> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" VECTOR_MAP_UNARY(T, N, trunc, x);\n") +SLANG_RAW("}\n") +SLANG_RAW("\n") +SLANG_RAW("__generic<T : __BuiltinFloatingPointType, let N : int, let M : int>\n") +SLANG_RAW("__target_intrinsic(hlsl)\n") +SLANG_RAW("matrix<T, N, M> trunc(matrix<T, N, M> x)\n") +SLANG_RAW("{\n") +SLANG_RAW(" MATRIX_MAP_UNARY(T, N, M, trunc, x);\n") +SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// Shader model 6.0 stuff\n") SLANG_RAW("\n") @@ -1671,37 +2410,6 @@ SLANG_RAW("// `typedef`s to help with the fact that HLSL has been sorta-kinda ca SLANG_RAW("typedef Texture2D texture2D;\n") SLANG_RAW("\n") -// Component-wise multiplication ops -for(auto op : binaryOps) -{ - switch (op.opCode) - { - default: - continue; - - case kIROp_Mul: - case kCompoundIntrinsicOp_MulAssign: - break; - } - - for (auto type : kBaseTypes) - { - if ((type.flags & op.flags) == 0) - continue; - - char const* leftType = type.name; - char const* rightType = leftType; - char const* resultType = leftType; - - char const* leftQual = ""; - if(op.flags & ASSIGNMENT) leftQual = "in out "; - - sb << "__generic<let N : int, let M : int> "; - sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftQual << "matrix<" << leftType << ",N,M> left, matrix<" << rightType << ",N,M> right);\n"; - } -} - -// // Buffer types @@ -1752,7 +2460,7 @@ for (int aa = 0; aa < kBaseBufferAccessLevelCount; ++aa) sb << "};\n"; } -SLANG_RAW("#line 1679 \"hlsl.meta.slang\"") +SLANG_RAW("#line 2387 \"hlsl.meta.slang\"") SLANG_RAW("\n") SLANG_RAW("\n") SLANG_RAW("\n") diff --git a/source/slang/slang-check.cpp b/source/slang/slang-check.cpp index dd28a9d71..275818614 100644 --- a/source/slang/slang-check.cpp +++ b/source/slang/slang-check.cpp @@ -71,7 +71,8 @@ namespace Slang switch (funcType) { - case FuncType::Glslang_Compile: return { "glslang_compile", PassThroughMode::Glslang} ; + case FuncType::Glslang_Compile_1_0: return { "glslang_compile", PassThroughMode::Glslang} ; + case FuncType::Glslang_Compile_1_1: return { "glslang_compile_1_1", PassThroughMode::Glslang} ; case FuncType::Fxc_D3DCompile: return { "D3DCompile", PassThroughMode::Fxc}; case FuncType::Fxc_D3DDisassemble: return { "D3DDisassemble", PassThroughMode::Fxc }; case FuncType::Dxc_DxcCreateInstance: return { "DxcCreateInstance", PassThroughMode::Dxc }; @@ -182,8 +183,11 @@ namespace Slang SlangFuncPtr func = sharedLibrary->findFuncByName(info.name); if (!func) { - UnownedStringSlice compilerName = TypeTextUtil::getPassThroughName(SlangPassThrough(info.compilerType)); - sink->diagnose(SourceLoc(), Diagnostics::failedToFindFunctionForCompiler, info.name, compilerName); + if (sink) + { + UnownedStringSlice compilerName = TypeTextUtil::getPassThroughName(SlangPassThrough(info.compilerType)); + sink->diagnose(SourceLoc(), Diagnostics::failedToFindFunctionForCompiler, info.name, compilerName); + } return nullptr; } diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 0da0bce9c..4ee69f1ad 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -8,6 +8,7 @@ #include "../core/slang-riff.h" #include "../core/slang-type-text-util.h" + #include "slang-check.h" #include "slang-compiler.h" #include "slang-lexer.h" @@ -20,6 +21,8 @@ #include "slang-reflection.h" #include "slang-emit.h" +#include "slang-glsl-extension-tracker.h" + #include "slang-ir-serialize.h" // Enable calling through to `fxc` or `dxc` to @@ -498,13 +501,16 @@ namespace Slang outCodeBuilder << fileContent << "\n"; } - String emitEntryPointSource( + SlangResult emitEntryPointSource( BackEndCompileRequest* compileRequest, Int entryPointIndex, TargetRequest* targetReq, CodeGenTarget target, - EndToEndCompileRequest* endToEndReq) + EndToEndCompileRequest* endToEndReq, + SourceResult& outSource) { + outSource.reset(); + if(auto translationUnit = findPassThroughTranslationUnit(endToEndReq, entryPointIndex)) { // Generate a string that includes the content of @@ -541,7 +547,9 @@ namespace Slang _appendCodeWithPath(sourceFile->getPathInfo().foundPath.getUnownedSlice(), sourceFile->getContent(), codeBuilder); } } - return codeBuilder.ProduceString(); + + outSource.source = codeBuilder.ProduceString(); + return SLANG_OK; } else { @@ -549,7 +557,8 @@ namespace Slang compileRequest, entryPointIndex, target, - targetReq); + targetReq, + outSource); } } @@ -836,7 +845,10 @@ namespace Slang return SLANG_FAIL; } - auto hlslCode = emitEntryPointSource(compileRequest, entryPointIndex, targetReq, CodeGenTarget::HLSL, endToEndReq); + SourceResult source; + SLANG_RETURN_ON_FAIL(emitEntryPointSource(compileRequest, entryPointIndex, targetReq, CodeGenTarget::HLSL, endToEndReq, source)); + + const auto& hlslCode = source.source; maybeDumpIntermediate(compileRequest, hlslCode.getBuffer(), CodeGenTarget::HLSL); auto profile = getEffectiveProfile(entryPoint, targetReq); @@ -1049,15 +1061,22 @@ SlangResult dissassembleDXILUsingDXC( #if SLANG_ENABLE_GLSLANG_SUPPORT SlangResult invokeGLSLCompiler( BackEndCompileRequest* slangCompileRequest, - glslang_CompileRequest& request) + glslang_CompileRequest_1_1& request) { + auto& request_1_0 = request.request_1_0; + Session* session = slangCompileRequest->getSession(); auto sink = slangCompileRequest->getSink(); auto linkage = slangCompileRequest->getLinkage(); - auto glslang_compile = (glslang_CompileFunc)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Glslang_Compile, sink); - if (!glslang_compile) + auto glslang_compile_1_0 = (glslang_CompileFunc_1_0)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Glslang_Compile_1_0, nullptr); + auto glslang_compile_1_1 = (glslang_CompileFunc_1_1)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Glslang_Compile_1_1, nullptr); + + if(glslang_compile_1_0 == nullptr && glslang_compile_1_1 == nullptr) { + // Try again and put diagnostic to the sink + session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Glslang_Compile_1_0, sink); + session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Glslang_Compile_1_1, sink); return SLANG_FAIL; } @@ -1068,13 +1087,21 @@ SlangResult dissassembleDXILUsingDXC( (*(StringBuilder*)userData).append((char const*)data, (char const*)data + size); }; - request.diagnosticFunc = diagnosticOutputFunc; - request.diagnosticUserData = &diagnosticOutput; + request_1_0.diagnosticFunc = diagnosticOutputFunc; + request_1_0.diagnosticUserData = &diagnosticOutput; - request.optimizationLevel = (unsigned)linkage->optimizationLevel; - request.debugInfoType = (unsigned)linkage->debugInfoLevel; + request_1_0.optimizationLevel = (unsigned)linkage->optimizationLevel; + request_1_0.debugInfoType = (unsigned)linkage->debugInfoLevel; - int err = glslang_compile(&request); + int err = 1; + if (glslang_compile_1_1) + { + err = glslang_compile_1_1(&request); + } + else if (glslang_compile_1_0) + { + err = glslang_compile_1_0(&request.request_1_0); + } if (err) { @@ -1099,16 +1126,23 @@ SlangResult dissassembleDXILUsingDXC( (*(String*)userData).append((char const*)data, (char const*)data + size); }; - glslang_CompileRequest request; - request.action = GLSLANG_ACTION_DISSASSEMBLE_SPIRV; + glslang_CompileRequest_1_1 request; + memset(&request, 0, sizeof(request)); + request.sizeInBytes = sizeof(request); - request.sourcePath = nullptr; + { + auto& request_1_0 = request.request_1_0; + + request_1_0.action = GLSLANG_ACTION_DISSASSEMBLE_SPIRV; - request.inputBegin = data; - request.inputEnd = (char*)data + size; + request_1_0.sourcePath = nullptr; - request.outputFunc = outputFunc; - request.outputUserData = &output; + request_1_0.inputBegin = data; + request_1_0.inputEnd = (char*)data + size; + + request_1_0.outputFunc = outputFunc; + request_1_0.outputUserData = &output; + } SLANG_RETURN_ON_FAIL(invokeGLSLCompiler(slangRequest, request)); @@ -1250,13 +1284,19 @@ SlangResult dissassembleDXILUsingDXC( } else { - options.sourceContents = emitEntryPointSource(slangRequest, entryPointIndex, targetReq, sourceTarget, endToEndReq); + SourceResult source; + SLANG_RETURN_ON_FAIL(emitEntryPointSource(slangRequest, entryPointIndex, targetReq, sourceTarget, endToEndReq, source)); + + options.sourceContents = source.source; } } else { - options.sourceContents = emitEntryPointSource(slangRequest, entryPointIndex, targetReq, sourceTarget, endToEndReq); + SourceResult source; + SLANG_RETURN_ON_FAIL(emitEntryPointSource(slangRequest, entryPointIndex, targetReq, sourceTarget, endToEndReq, source)); + options.sourceContents = source.source; + maybeDumpIntermediate(slangRequest, options.sourceContents.getBuffer(), sourceTarget); } @@ -1422,12 +1462,12 @@ SlangResult dissassembleDXILUsingDXC( { spirvOut.clear(); - String rawGLSL = emitEntryPointSource( - slangRequest, - entryPointIndex, - targetReq, - CodeGenTarget::GLSL, - endToEndReq); + SourceResult source; + + SLANG_RETURN_ON_FAIL(emitEntryPointSource(slangRequest, entryPointIndex, targetReq, CodeGenTarget::GLSL, endToEndReq, source)); + + const auto& rawGLSL = source.source; + maybeDumpIntermediate(slangRequest, rawGLSL.getBuffer(), CodeGenTarget::GLSL); auto outputFunc = [](void const* data, size_t size, void* userData) @@ -1437,16 +1477,31 @@ SlangResult dissassembleDXILUsingDXC( const String sourcePath = calcSourcePathForEntryPoint(endToEndReq, entryPointIndex); - glslang_CompileRequest request; - request.action = GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV; - request.sourcePath = sourcePath.getBuffer(); - request.slangStage = (SlangStage)entryPoint->getStage(); + glslang_CompileRequest_1_1 request; + memset(&request, 0, sizeof(request)); + request.sizeInBytes = sizeof(request); + + auto& request_1_0 = request.request_1_0; - request.inputBegin = rawGLSL.begin(); - request.inputEnd = rawGLSL.end(); + request_1_0.action = GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV; + request_1_0.sourcePath = sourcePath.getBuffer(); + request_1_0.slangStage = (SlangStage)entryPoint->getStage(); - request.outputFunc = outputFunc; - request.outputUserData = &spirvOut; + request_1_0.inputBegin = rawGLSL.begin(); + request_1_0.inputEnd = rawGLSL.end(); + + if (GLSLExtensionTracker* tracker = as<GLSLExtensionTracker>(source.extensionTracker.Ptr())) + { + request.spirvTargetName = nullptr; + auto spirvLanguageVersion = tracker->getSPIRVVersion(); + + request.spirvVersion.major = spirvLanguageVersion.m_major; + request.spirvVersion.minor = spirvLanguageVersion.m_minor; + request.spirvVersion.patch = spirvLanguageVersion.m_patch; + } + + request_1_0.outputFunc = outputFunc; + request_1_0.outputUserData = &spirvOut; SLANG_RETURN_ON_FAIL(invokeGLSLCompiler(slangRequest, request)); return SLANG_OK; @@ -1544,12 +1599,13 @@ SlangResult dissassembleDXILUsingDXC( case CodeGenTarget::CPPSource: case CodeGenTarget::CSource: { - String code = emitEntryPointSource( - compileRequest, - entryPointIndex, - targetReq, - target, - endToEndReq); + SourceResult source; + if (SLANG_FAILED(emitEntryPointSource(compileRequest, entryPointIndex, targetReq, target, endToEndReq, source))) + { + return result; + } + + const auto& code = source.source; maybeDumpIntermediate(compileRequest, code.getBuffer(), target); result = CompileResult(code); } diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index e337c2fff..7cfc4fac1 100644 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -1902,19 +1902,33 @@ namespace Slang If the end-to-end compile is a pass-through case, will attempt to find the (unique) source file pathname for the translation unit containing the entry point at `entryPointIndex. If the compilation is not in a pass-through case, then always returns `"slang-generated"`. - @param endToEndReq The end-to-end compile request which might be using pass-through copmilation + @param endToEndReq The end-to-end compile request which might be using pass-through compilation @param entryPointIndex The index of the entry point to compute a filename for. @return the appropriate source filename */ String calcSourcePathForEntryPoint(EndToEndCompileRequest* endToEndReq, UInt entryPointIndex); + struct SourceResult + { + void reset() + { + source = String(); + extensionTracker.setNull(); + } + + String source; + // Must be cast to a specific extension tracker such as GLSLExtensionTracker + RefPtr<RefObject> extensionTracker; + }; + /* Emits entry point source taking into account if a pass-through or not. Uses 'target' to determine the target (not targetReq) */ - String emitEntryPointSource( + SlangResult emitEntryPointSource( BackEndCompileRequest* compileRequest, Int entryPointIndex, TargetRequest* targetReq, CodeGenTarget target, - EndToEndCompileRequest* endToEndReq); + EndToEndCompileRequest* endToEndReq, + SourceResult& outSource); struct TypeCheckingCache; // @@ -1986,7 +2000,8 @@ namespace Slang enum class SharedLibraryFuncType { - Glslang_Compile, + Glslang_Compile_1_0, + Glslang_Compile_1_1, Fxc_D3DCompile, Fxc_D3DDisassemble, Dxc_DxcCreateInstance, diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index de3b9dac3..ff64b023c 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -207,7 +207,7 @@ DIAGNOSTIC(20002, Error, syntaxError, "syntax error."); DIAGNOSTIC(20004, Error, unexpectedTokenExpectedComponentDefinition, "unexpected token '$0', only component definitions are allowed in a shader scope.") DIAGNOSTIC(20008, Error, invalidOperator, "invalid operator '$0'."); DIAGNOSTIC(20011, Error, unexpectedColon, "unexpected ':'.") -DIAGNOSTIC(20012, Error, invalidSPIRVVersion, "Expecting SPIR-V version number as either 'major.minor' or 'spirv_major_minor' (eg for SPIR-V 1.2, '1.2' or 'spirv_1_2')") +DIAGNOSTIC(20012, Error, invalidSPIRVVersion, "Expecting SPIR-V version as either 'major.minor', or quoted if has patch (eg for SPIR-V 1.2, '1.2' or \"1.2\"')") // // 3xxxx - Semantic analysis diff --git a/source/slang/slang-dxc-support.cpp b/source/slang/slang-dxc-support.cpp index 828138143..4fe8e64ca 100644 --- a/source/slang/slang-dxc-support.cpp +++ b/source/slang/slang-dxc-support.cpp @@ -81,12 +81,11 @@ namespace Slang // Now let's go ahead and generate HLSL for the entry // point, since we'll need that to feed into dxc. - auto hlslCode = emitEntryPointSource( - compileRequest, - entryPointIndex, - targetReq, - CodeGenTarget::HLSL, - endToEndReq); + SourceResult source; + SLANG_RETURN_ON_FAIL(emitEntryPointSource(compileRequest, entryPointIndex, targetReq, CodeGenTarget::HLSL, endToEndReq, source)); + + const auto& hlslCode = source.source; + maybeDumpIntermediate(compileRequest, hlslCode.getBuffer(), CodeGenTarget::HLSL); // Wrap the diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h index 8381f194f..ddca69462 100644 --- a/source/slang/slang-emit-c-like.h +++ b/source/slang/slang-emit-c-like.h @@ -6,7 +6,6 @@ #include "slang-compiler.h" -#include "slang-emit-glsl-extension-tracker.h" #include "slang-emit-precedence.h" #include "slang-emit-source-writer.h" @@ -114,8 +113,6 @@ public: void noteInternalErrorLoc(SourceLoc loc) { return getSink()->noteInternalErrorLoc(loc); } - GLSLExtensionTracker* getGLSLExtensionTracker() { return &m_glslExtensionTracker; } - // // Types // @@ -294,6 +291,8 @@ public: void emitVectorTypeName(IRType* elementType, IRIntegerValue elementCount) { emitVectorTypeNameImpl(elementType, elementCount); } + virtual RefObject* getExtensionTracker() { return nullptr; } + /// Gets a source style for a target. Returns Unknown if not a known target static SourceStyle getSourceStyle(CodeGenTarget target); /// Gets the default type name for built in scalar types. Different impls may require something different. @@ -370,8 +369,6 @@ public: ModuleDecl* m_program; - GLSLExtensionTracker m_glslExtensionTracker; - UInt m_uniqueIDCounter = 1; Dictionary<IRInst*, UInt> m_mapIRValueToID; Dictionary<Decl*, UInt> m_mapDeclToID; diff --git a/source/slang/slang-emit-glsl-extension-tracker.h b/source/slang/slang-emit-glsl-extension-tracker.h deleted file mode 100644 index 4b1b8b720..000000000 --- a/source/slang/slang-emit-glsl-extension-tracker.h +++ /dev/null @@ -1,39 +0,0 @@ -// slang-emit-glsl-extension-tracker.h -#ifndef SLANG_EMIT_GLSL_EXTENSION_TRACKER_H -#define SLANG_EMIT_GLSL_EXTENSION_TRACKER_H - -#include "../core/slang-basic.h" - -#include "slang-compiler.h" - -namespace Slang -{ - -class GLSLExtensionTracker -{ -public: - - void requireExtension(const String& name); - void requireVersion(ProfileVersion version); - void requireBaseTypeExtension(BaseType baseType); - void requireSPIRVVersion(SPIRVVersion version); - - ProfileVersion getRequiredProfileVersion() const { return m_profileVersion; } - const StringBuilder& getExtensionRequireLines() const { return m_extensionRequireLines; } - -protected: - // Record the GLSL extensions we have already emitted a `#extension` for - HashSet<String> m_extensionsRequired; - StringBuilder m_extensionRequireLines; - - SPIRVVersion m_spirvVersion = makeSPIRVVersion(1, 2); - - ProfileVersion m_profileVersion = ProfileVersion::GLSL_110; - - 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)); -}; - -} -#endif diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 131c1882d..155b86a9c 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -12,9 +12,9 @@ namespace Slang { -void GLSLSourceEmitter::_requireGLSLExtension(String const& name) +void GLSLSourceEmitter::_requireGLSLExtension(const UnownedStringSlice& name) { - m_glslExtensionTracker.requireExtension(name); + m_glslExtensionTracker->requireExtension(name); } void GLSLSourceEmitter::_requireGLSLVersion(ProfileVersion version) @@ -22,12 +22,12 @@ void GLSLSourceEmitter::_requireGLSLVersion(ProfileVersion version) if (getSourceStyle() != SourceStyle::GLSL) return; - m_glslExtensionTracker.requireVersion(version); + m_glslExtensionTracker->requireVersion(version); } -void GLSLSourceEmitter::_requireSPIRVVersion(SPIRVVersion version) +void GLSLSourceEmitter::_requireSPIRVVersion(const SemanticVersion& version) { - m_glslExtensionTracker.requireSPIRVVersion(version); + m_glslExtensionTracker->requireSPIRVVersion(version); } void GLSLSourceEmitter::_requireGLSLVersion(int version) @@ -284,7 +284,7 @@ void GLSLSourceEmitter::_emitGLSLImageFormatModifier(IRInst* var, IRTextureType* // the image *type* (with a "base type" for images with // unknown format). // - _requireGLSLExtension("GL_EXT_shader_image_load_formatted"); + _requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_EXT_shader_image_load_formatted")); } else { @@ -316,7 +316,7 @@ void GLSLSourceEmitter::_emitGLSLImageFormatModifier(IRInst* var, IRTextureType* // if (m_compileRequest->useUnknownImageFormatAsDefault) { - _requireGLSLExtension("GL_EXT_shader_image_load_formatted"); + _requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_EXT_shader_image_load_formatted")); return; } @@ -466,7 +466,7 @@ bool GLSLSourceEmitter::_emitGLSLLayoutQualifier(LayoutResourceKind kind, EmitVa bool useExplicitOffsets = false; if (useExplicitOffsets) { - _requireGLSLExtension("GL_ARB_enhanced_layouts"); + _requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_ARB_enhanced_layouts")); m_writer->emit("layout(offset = "); m_writer->emit(index); @@ -644,7 +644,7 @@ void GLSLSourceEmitter::_emitGLSLTypePrefix(IRType* type, bool promoteHalfToFloa void GLSLSourceEmitter::_requireBaseType(BaseType baseType) { - m_glslExtensionTracker.requireBaseTypeExtension(baseType); + m_glslExtensionTracker->requireBaseTypeExtension(baseType); } void GLSLSourceEmitter::_maybeEmitGLSLFlatModifier(IRType* valueType) @@ -923,7 +923,7 @@ bool GLSLSourceEmitter::tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* v { if (isResourceType(unwrapArray(varType))) { - _requireGLSLExtension("GL_EXT_nonuniform_qualifier"); + _requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_EXT_nonuniform_qualifier")); } } @@ -1333,7 +1333,7 @@ void GLSLSourceEmitter::handleCallExprDecorationsImpl(IRInst* funcValue) case kIROp_RequireGLSLExtensionDecoration: { - _requireGLSLExtension(String(((IRRequireGLSLExtensionDecoration*)decoration)->getExtensionName())); + _requireGLSLExtension(((IRRequireGLSLExtensionDecoration*)decoration)->getExtensionName()); break; } case kIROp_RequireGLSLVersionDecoration: @@ -1343,7 +1343,10 @@ void GLSLSourceEmitter::handleCallExprDecorationsImpl(IRInst* funcValue) } case kIROp_RequireSPIRVVersionDecoration: { - _requireSPIRVVersion(static_cast<IRRequireSPIRVVersionDecoration*>(decoration)->getSPIRVVersion()); + auto intValue = static_cast<IRRequireSPIRVVersionDecoration*>(decoration)->getSPIRVVersion(); + SemanticVersion version; + version.setFromInteger(SemanticVersion::IntegerType(intValue)); + _requireSPIRVVersion(version); break; } @@ -1368,9 +1371,9 @@ void GLSLSourceEmitter::emitPreprocessorDirectivesImpl() // // TODO: Either correctly compute a minimum required version, or require // the user to specify a version as part of the target. - m_glslExtensionTracker.requireVersion(ProfileVersion::GLSL_450); + m_glslExtensionTracker->requireVersion(ProfileVersion::GLSL_450); - auto requiredProfileVersion = m_glslExtensionTracker.getRequiredProfileVersion(); + auto requiredProfileVersion = m_glslExtensionTracker->getRequiredProfileVersion(); switch (requiredProfileVersion) { #define CASE(TAG, VALUE) \ @@ -1565,7 +1568,7 @@ void GLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) switch (untypedBufferType->op) { case kIROp_RaytracingAccelerationStructureType: - _requireGLSLExtension("GL_NV_ray_tracing"); + _requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_NV_ray_tracing")); m_writer->emit("accelerationStructureNV"); break; diff --git a/source/slang/slang-emit-glsl.h b/source/slang/slang-emit-glsl.h index fcd398748..a88a3b39b 100644 --- a/source/slang/slang-emit-glsl.h +++ b/source/slang/slang-emit-glsl.h @@ -4,6 +4,8 @@ #include "slang-emit-c-like.h" +#include "slang-glsl-extension-tracker.h" + namespace Slang { @@ -15,8 +17,11 @@ public: GLSLSourceEmitter(const Desc& desc) : Super(desc) { + m_glslExtensionTracker = new GLSLExtensionTracker; } + virtual RefObject* getExtensionTracker() SLANG_OVERRIDE { return m_glslExtensionTracker; } + protected: virtual void emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) SLANG_OVERRIDE; @@ -56,11 +61,11 @@ protected: void _emitGLSLTypePrefix(IRType* type, bool promoteHalfToFloat = false); - void _requireGLSLExtension(const String& name); + void _requireGLSLExtension(const UnownedStringSlice& name); void _requireGLSLVersion(ProfileVersion version); void _requireGLSLVersion(int version); - void _requireSPIRVVersion(SPIRVVersion version); + void _requireSPIRVVersion(const SemanticVersion& version); // Emit the `flat` qualifier if the underlying type // of the variable is an integer type. @@ -69,6 +74,9 @@ protected: void _requireBaseType(BaseType baseType); void _maybeEmitGLSLCast(IRType* castType, IRInst* inst); + + + RefPtr<GLSLExtensionTracker> m_glslExtensionTracker; }; } diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index d5dc9cbe7..dcca7d25e 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -421,12 +421,14 @@ Result linkAndOptimizeIR( { case CodeGenTarget::GLSL: { + auto glslExtensionTracker = as<GLSLExtensionTracker>(options.sourceEmitter->getExtensionTracker()); + legalizeEntryPointForGLSL( session, irModule, irEntryPoint, compileRequest->getSink(), - options.sourceEmitter->getGLSLExtensionTracker()); + glslExtensionTracker); #if 0 dumpIRIfEnabled(compileRequest, irModule, "GLSL LEGALIZED"); @@ -458,12 +460,15 @@ Result linkAndOptimizeIR( return SLANG_OK; } -String emitEntryPointSourceFromIR( +SlangResult emitEntryPointSourceFromIR( BackEndCompileRequest* compileRequest, Int entryPointIndex, CodeGenTarget target, - TargetRequest* targetRequest) + TargetRequest* targetRequest, + SourceResult& outSource) { + outSource.reset(); + auto sink = compileRequest->getSink(); auto program = compileRequest->getProgram(); @@ -496,7 +501,7 @@ String emitEntryPointSourceFromIR( LinkedIR linkedIR; RefPtr<CLikeSourceEmitter> sourceEmitter; - + typedef CLikeSourceEmitter::SourceStyle SourceStyle; SourceStyle sourceStyle = CLikeSourceEmitter::getSourceStyle(target); @@ -528,7 +533,7 @@ String emitEntryPointSourceFromIR( if (!sourceEmitter) { sink->diagnose(SourceLoc(), Diagnostics::unableToGenerateCodeForTarget, TypeTextUtil::getCompileTargetName(SlangCompileTarget(target))); - return String(); + return SLANG_FAIL; } { @@ -582,8 +587,10 @@ String emitEntryPointSourceFromIR( case Stage::RayGeneration: if( target == CodeGenTarget::GLSL ) { - sourceEmitter->getGLSLExtensionTracker()->requireExtension("GL_NV_ray_tracing"); - sourceEmitter->getGLSLExtensionTracker()->requireVersion(ProfileVersion::GLSL_460); + auto glslExtensionTracker = as<GLSLExtensionTracker>(sourceEmitter->getExtensionTracker()); + + glslExtensionTracker->requireExtension(UnownedStringSlice::fromLiteral("GL_NV_ray_tracing")); + glslExtensionTracker->requireVersion(ProfileVersion::GLSL_460); } break; } @@ -630,13 +637,20 @@ String emitEntryPointSourceFromIR( StringBuilder finalResultBuilder; finalResultBuilder << prefix; - finalResultBuilder << sourceEmitter->getGLSLExtensionTracker()->getExtensionRequireLines(); + RefObject* extensionTracker = sourceEmitter->getExtensionTracker(); + + if (auto glslExtensionTracker = as<GLSLExtensionTracker>(extensionTracker)) + { + glslExtensionTracker->appendExtensionRequireLines(finalResultBuilder); + } finalResultBuilder << code; - String finalResult = finalResultBuilder.ProduceString(); + // Write out the result + outSource.source = finalResultBuilder.ProduceString(); + outSource.extensionTracker = extensionTracker; - return finalResult; + return SLANG_OK; } SlangResult emitSPIRVFromIR( diff --git a/source/slang/slang-emit.h b/source/slang/slang-emit.h index 1f3298316..e18ba6f01 100644 --- a/source/slang/slang-emit.h +++ b/source/slang/slang-emit.h @@ -12,6 +12,8 @@ namespace Slang class ProgramLayout; class TranslationUnitRequest; + + /// Emit source code for a single entry point. /// /// This function generates source code for the @@ -34,10 +36,11 @@ namespace Slang /// generate different HLSL output if we know it /// will be used to generate SPIR-V). /// - String emitEntryPointSourceFromIR( + SlangResult emitEntryPointSourceFromIR( BackEndCompileRequest* compileRequest, Int entryPointIndex, CodeGenTarget target, - TargetRequest* targetRequest); + TargetRequest* targetRequest, + SourceResult& outSource); } #endif diff --git a/source/slang/slang-emit-glsl-extension-tracker.cpp b/source/slang/slang-glsl-extension-tracker.cpp index 6f2bc678c..30acd8936 100644 --- a/source/slang/slang-emit-glsl-extension-tracker.cpp +++ b/source/slang/slang-glsl-extension-tracker.cpp @@ -1,36 +1,32 @@ -// slang-emit-glsl-extension-tracker.cpp -#include "slang-emit-glsl-extension-tracker.h" +// slang-glsl-extension-tracker.cpp +#include "slang-glsl-extension-tracker.h" namespace Slang { -void GLSLExtensionTracker::requireExtension(const String& name) +void GLSLExtensionTracker::appendExtensionRequireLines(StringBuilder& ioBuilder) const { - if (m_extensionsRequired.Contains(name)) - return; - - StringBuilder& sb = m_extensionRequireLines; - - sb.append("#extension "); - sb.append(name); - sb.append(" : require\n"); - - m_extensionsRequired.Add(name); + for (const auto& extension : m_extensionPool.getSlices()) + { + ioBuilder.append("#extension "); + ioBuilder.append(extension); + ioBuilder.append(" : require\n"); + } } -void GLSLExtensionTracker::requireVersion(ProfileVersion version) +void GLSLExtensionTracker::requireSPIRVVersion(const SemanticVersion& version) { - // Check if this profile is newer - if ((UInt)version > (UInt)m_profileVersion) + if (version > m_spirvVersion) { - m_profileVersion = version; + m_spirvVersion = version; } } -void GLSLExtensionTracker::requireSPIRVVersion(SPIRVVersion version) +void GLSLExtensionTracker::requireVersion(ProfileVersion version) { - if (asInteger(version) > asInteger(m_spirvVersion)) + // Check if this profile is newer + if ((UInt)version > (UInt)m_profileVersion) { - m_spirvVersion = version; + m_profileVersion = version; } } @@ -47,16 +43,16 @@ void GLSLExtensionTracker::requireBaseTypeExtension(BaseType 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"); + requireExtension(UnownedStringSlice::fromLiteral("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"); + requireExtension(UnownedStringSlice::fromLiteral("GL_EXT_shader_explicit_arithmetic_types")); break; } case BaseType::UInt64: case BaseType::Int64: { - requireExtension("GL_EXT_shader_explicit_arithmetic_types_int64"); + requireExtension(UnownedStringSlice::fromLiteral("GL_EXT_shader_explicit_arithmetic_types_int64")); m_hasBaseTypeFlags |= _getFlag(BaseType::UInt64) | _getFlag(BaseType::Int64); break; } @@ -65,5 +61,4 @@ void GLSLExtensionTracker::requireBaseTypeExtension(BaseType baseType) m_hasBaseTypeFlags |= bit; } - } // namespace Slang diff --git a/source/slang/slang-glsl-extension-tracker.h b/source/slang/slang-glsl-extension-tracker.h new file mode 100644 index 000000000..79dcd720e --- /dev/null +++ b/source/slang/slang-glsl-extension-tracker.h @@ -0,0 +1,50 @@ +// slang-glsl-extension-tracker.h +#ifndef SLANG_GLSL_EXTENSION_TRACKER_H +#define SLANG_GLSL_EXTENSION_TRACKER_H + +#include "../core/slang-basic.h" + +#include "../core/slang-string-slice-pool.h" +#include "../core/slang-semantic-version.h" + +#include "slang-compiler.h" + +namespace Slang +{ + +class GLSLExtensionTracker : public RefObject +{ +public: + + /// Return the list of extensionsspecified. NOTE that they are specified in the order requested, and they *do* have terminating zeros + const List<UnownedStringSlice>& getExtensions() const { return m_extensionPool.getSlices(); } + + void requireExtension(const UnownedStringSlice& name) { m_extensionPool.add(name); } + void requireVersion(ProfileVersion version); + void requireBaseTypeExtension(BaseType baseType); + void requireSPIRVVersion(const SemanticVersion& version); + + ProfileVersion getRequiredProfileVersion() const { return m_profileVersion; } + void appendExtensionRequireLines(StringBuilder& builder) const; + + const SemanticVersion& getSPIRVVersion() const { return m_spirvVersion; } + + GLSLExtensionTracker(): + m_extensionPool(StringSlicePool::Style::Empty) + { + } + +protected: + 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)); + + ProfileVersion m_profileVersion = ProfileVersion::GLSL_110; + + StringSlicePool m_extensionPool; + + SemanticVersion m_spirvVersion; +}; + +} +#endif diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index 15a7e3c67..c7dfb242f 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -4,7 +4,7 @@ #include "slang-ir.h" #include "slang-ir-insts.h" -#include "slang-emit-glsl-extension-tracker.h" +#include "slang-glsl-extension-tracker.h" namespace Slang { @@ -183,12 +183,12 @@ struct GLSLLegalizationContext DiagnosticSink* sink; Stage stage; - void requireGLSLExtension(String const& name) + void requireGLSLExtension(const UnownedStringSlice& name) { glslExtensionTracker->requireExtension(name); } - void requireSPIRVVersion(SPIRVVersion version) + void requireSPIRVVersion(const SemanticVersion& version) { glslExtensionTracker->requireSPIRVVersion(version); } @@ -297,7 +297,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( // float in hlsl & glsl. // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_CullDistance.xhtml - context->requireGLSLExtension("ARB_cull_distance"); + context->requireGLSLExtension(UnownedStringSlice::fromLiteral("ARB_cull_distance")); // TODO: type conversion is required here. name = "gl_CullDistance"; @@ -475,7 +475,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( default: context->requireGLSLVersion(ProfileVersion::GLSL_450); - context->requireGLSLExtension("GL_ARB_shader_viewport_layer_array"); + context->requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_ARB_shader_viewport_layer_array")); break; } @@ -497,7 +497,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( requiredType = builder->getBasicType(BaseType::Int); - context->requireGLSLExtension("ARB_shader_stencil_export"); + context->requireGLSLExtension(UnownedStringSlice::fromLiteral("ARB_shader_stencil_export")); name = "gl_FragStencilRef"; } else if (semanticName == "sv_tessfactor") @@ -535,7 +535,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( else if (semanticName == "nv_x_right") { context->requireGLSLVersion(ProfileVersion::GLSL_450); - context->requireGLSLExtension("GL_NVX_multiview_per_view_attributes"); + context->requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_NVX_multiview_per_view_attributes")); // The actual output in GLSL is: // @@ -569,7 +569,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( // On glsl its highp int gl_ViewportMaskPerViewNV[]; context->requireGLSLVersion(ProfileVersion::GLSL_450); - context->requireGLSLExtension("GL_NVX_multiview_per_view_attributes"); + context->requireGLSLExtension(UnownedStringSlice::fromLiteral("GL_NVX_multiview_per_view_attributes")); name = "gl_ViewportMaskPerViewNV"; // globalVarExpr = createGLSLBuiltinRef("gl_ViewportMaskPerViewNV", diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index bacc3986c..76d2a8940 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -184,10 +184,9 @@ struct IRRequireSPIRVVersionDecoration : IRDecoration IR_LEAF_ISA(RequireGLSLVersionDecoration) IRConstant* getSPIRVVersionOperand() { return cast<IRConstant>(getOperand(0)); } - - SPIRVVersion getSPIRVVersion() + IntegerLiteralValue getSPIRVVersion() { - return SPIRVVersion(getSPIRVVersionOperand()->value.intVal); + return getSPIRVVersionOperand()->value.intVal; } }; @@ -2123,9 +2122,10 @@ struct IRBuilder addDecoration(value, kIROp_RequireGLSLVersionDecoration, getIntValue(getIntType(), IRIntegerValue(version))); } - void addRequireSPIRVVersionDecoration(IRInst* value, SPIRVVersion version) + void addRequireSPIRVVersionDecoration(IRInst* value, const SemanticVersion& version) { - addDecoration(value, kIROp_RequireSPIRVVersionDecoration, getIntValue(getIntType(), IRIntegerValue(version))); + SemanticVersion::IntegerType intValue = version.toInteger(); + addDecoration(value, kIROp_RequireSPIRVVersionDecoration, getIntValue(getBasicType(BaseType::UInt64), intValue)); } void addPatchConstantFuncDecoration(IRInst* value, IRInst* patchConstantFunc) diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 57494f83f..12d7245b8 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -6294,7 +6294,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> } for (auto versionMod : decl->GetModifiersOfType<RequiredSPIRVVersionModifier>()) { - getBuilder()->addRequireSPIRVVersionDecoration(irFunc, versionMod->spirvVersion); + getBuilder()->addRequireSPIRVVersionDecoration(irFunc, versionMod->version); } diff --git a/source/slang/slang-modifier-defs.h b/source/slang/slang-modifier-defs.h index 40ed945ae..aa9b25d00 100644 --- a/source/slang/slang-modifier-defs.h +++ b/source/slang/slang-modifier-defs.h @@ -85,8 +85,7 @@ END_SYNTAX_CLASS() // A modifier to tag something as an intrinsic that requires // a certain SPIRV version to be enabled when used. Specified as "major.minor" SYNTAX_CLASS(RequiredSPIRVVersionModifier, Modifier) -FIELD(Token, token) -FIELD(SPIRVVersion, spirvVersion) +FIELD(SemanticVersion, version) END_SYNTAX_CLASS() SIMPLE_SYNTAX_CLASS(InOutModifier, OutModifier) diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 9dfe7ddc6..94ab58c07 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -7,6 +7,8 @@ #include "slang-lookup.h" #include "slang-visitor.h" +#include "../core/slang-semantic-version.h" + namespace Slang { // pre-declare @@ -4752,81 +4754,39 @@ namespace Slang auto modifier = new RequiredSPIRVVersionModifier(); parser->ReadToken(TokenType::LParent); + Token token = parser->ReadToken(); + parser->ReadToken(TokenType::RParent); - UnownedStringSlice typeName; - UnownedStringSlice majorVersionText; - UnownedStringSlice minorVersionText; - - // There is a legitimate question about how the version should be handled here. - switch (parser->tokenReader.peekTokenType()) + UnownedStringSlice content = token.Content; + // We allow specified as major.minor or as a string (in quotes) + switch (token.type) { case TokenType::FloatingPointLiteral: { - modifier->token = parser->ReadToken(TokenType::FloatingPointLiteral); - - List<UnownedStringSlice> split; - StringUtil::split(modifier->token.Content, '.', split); - - if (split.getCount() != 2) - { - parser->sink->diagnose(modifier->token, Diagnostics::invalidSPIRVVersion); - return RefPtr<RefObject>(); - } - - majorVersionText = split[0]; - minorVersionText = split[1]; break; } - case TokenType::Identifier: + case TokenType::StringLiteral: { - modifier->token = parser->ReadToken(TokenType::Identifier); - - List<UnownedStringSlice> split; - StringUtil::split(modifier->token.Content, '_', split); - - if (split.getCount() != 3) - { - parser->sink->diagnose(modifier->token, Diagnostics::invalidSPIRVVersion); - return RefPtr<RefObject>(); - } - - typeName = split[0]; - majorVersionText = split[1]; - minorVersionText = split[2]; + // We need to trim quotes if needed + SLANG_ASSERT(content.getLength() >= 2 && content[0] == '"' && content[content.getLength() -1] == '"'); + content = UnownedStringSlice(content.begin() + 1, content.end() - 1); break; - } default: { - parser->sink->diagnose(modifier->token, Diagnostics::invalidSPIRVVersion); + parser->sink->diagnose(token, Diagnostics::invalidSPIRVVersion); return RefPtr<RefObject>(); } } - - parser->ReadToken(TokenType::RParent); - - // Currently we only support 'spirv' or no typename - if (!(typeName == UnownedStringSlice::fromLiteral("spirv") || typeName.getLength() == 0)) - { - parser->sink->diagnose(modifier->token, Diagnostics::invalidSPIRVVersion); - return RefPtr<RefObject>(); - } - - Token intToken = modifier->token; - intToken.type = TokenType::IntegerLiteral; - intToken.Content = majorVersionText; - - auto majorValue = getIntegerLiteralValue(intToken); - intToken.Content = minorVersionText; - auto minorValue = getIntegerLiteralValue(intToken); - - if (minorValue < 0 || minorValue > 0xff || majorValue < 0) + + SemanticVersion version; + if (SLANG_FAILED(SemanticVersion::parse(content, modifier->version))) { - parser->sink->diagnose(modifier->token, Diagnostics::invalidSPIRVVersion); + // Unable to parse the error so fail + parser->sink->diagnose(token, Diagnostics::invalidSPIRVVersion); return RefPtr<RefObject>(); } - modifier->spirvVersion = makeSPIRVVersion(int(majorValue), int(minorValue)); return modifier; } diff --git a/source/slang/slang-profile.h b/source/slang/slang-profile.h index b8d5257bb..1ae752d5a 100644 --- a/source/slang/slang-profile.h +++ b/source/slang/slang-profile.h @@ -109,19 +109,6 @@ namespace Slang Stage findStageByName(String const& name); UnownedStringSlice getStageText(Stage stage); - - - // An enum to specify SPIR-V versions. - // For the moment they are only differentiated by version number, but it may be necessary to - // differentiate specific versions in other ways (such as the VK1.1 / SPIR-V combination in - // glslang). The enum is used to encode the representation, and vary as is needed in - // an implementation. - enum class SPIRVVersion : uint32_t; - - SLANG_INLINE SPIRVVersion makeSPIRVVersion(int major, int minor) { return SPIRVVersion((uint32_t(major) << 8) | uint32_t(minor)); } - SLANG_FORCE_INLINE Index getMajorVersion(SPIRVVersion version) { return Index((uint32_t(version) >> 8) & 0xff); } - SLANG_FORCE_INLINE Index getMinorVersion(SPIRVVersion version) { return Index(uint32_t(version) & 0xff); } - SLANG_FORCE_INLINE int32_t asInteger(SPIRVVersion version) { return int32_t(version); } } #endif diff --git a/source/slang/slang-syntax.h b/source/slang/slang-syntax.h index 7a7ea3603..f8f506236 100644 --- a/source/slang/slang-syntax.h +++ b/source/slang/slang-syntax.h @@ -8,6 +8,8 @@ #include "slang-type-system-shared.h" #include "../../slang.h" +#include "../core/slang-semantic-version.h" + #include "slang-name.h" #include <assert.h> @@ -32,8 +34,6 @@ namespace Slang class Parser; class SyntaxNode; - enum class SPIRVVersion : uint32_t; - typedef RefPtr<RefObject> (*SyntaxParseCallback)(Parser* parser, void* userData); typedef unsigned int ConversionCost; diff --git a/source/slang/slang.vcxproj b/source/slang/slang.vcxproj index 6c35986a2..76cffe08b 100644 --- a/source/slang/slang.vcxproj +++ b/source/slang/slang.vcxproj @@ -200,7 +200,6 @@ <ClInclude Include="slang-emit-c-like.h" /> <ClInclude Include="slang-emit-cpp.h" /> <ClInclude Include="slang-emit-cuda.h" /> - <ClInclude Include="slang-emit-glsl-extension-tracker.h" /> <ClInclude Include="slang-emit-glsl.h" /> <ClInclude Include="slang-emit-hlsl.h" /> <ClInclude Include="slang-emit-precedence.h" /> @@ -208,6 +207,7 @@ <ClInclude Include="slang-emit.h" /> <ClInclude Include="slang-expr-defs.h" /> <ClInclude Include="slang-file-system.h" /> + <ClInclude Include="slang-glsl-extension-tracker.h" /> <ClInclude Include="slang-hlsl-intrinsic-set.h" /> <ClInclude Include="slang-image-format-defs.h" /> <ClInclude Include="slang-ir-bind-existentials.h" /> @@ -285,7 +285,6 @@ <ClCompile Include="slang-emit-c-like.cpp" /> <ClCompile Include="slang-emit-cpp.cpp" /> <ClCompile Include="slang-emit-cuda.cpp" /> - <ClCompile Include="slang-emit-glsl-extension-tracker.cpp" /> <ClCompile Include="slang-emit-glsl.cpp" /> <ClCompile Include="slang-emit-hlsl.cpp" /> <ClCompile Include="slang-emit-precedence.cpp" /> @@ -293,6 +292,7 @@ <ClCompile Include="slang-emit-spirv.cpp" /> <ClCompile Include="slang-emit.cpp" /> <ClCompile Include="slang-file-system.cpp" /> + <ClCompile Include="slang-glsl-extension-tracker.cpp" /> <ClCompile Include="slang-hlsl-intrinsic-set.cpp" /> <ClCompile Include="slang-ir-bind-existentials.cpp" /> <ClCompile Include="slang-ir-clone.cpp" /> diff --git a/source/slang/slang.vcxproj.filters b/source/slang/slang.vcxproj.filters index 75bf8abc0..449f72069 100644 --- a/source/slang/slang.vcxproj.filters +++ b/source/slang/slang.vcxproj.filters @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="Header Files"> @@ -51,9 +51,6 @@ <ClInclude Include="slang-emit-cuda.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="slang-emit-glsl-extension-tracker.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="slang-emit-glsl.h"> <Filter>Header Files</Filter> </ClInclude> @@ -75,6 +72,9 @@ <ClInclude Include="slang-file-system.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slang-glsl-extension-tracker.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="slang-hlsl-intrinsic-set.h"> <Filter>Header Files</Filter> </ClInclude> @@ -153,6 +153,9 @@ <ClInclude Include="slang-ir-validate.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slang-ir-wrap-structured-buffers.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="slang-ir.h"> <Filter>Header Files</Filter> </ClInclude> @@ -246,9 +249,6 @@ <ClInclude Include="slang-visitor.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="slang-ir-wrap-structured-buffers.h"> - <Filter>Header Files</Filter> - </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="slang-check-conformance.cpp"> @@ -302,9 +302,6 @@ <ClCompile Include="slang-emit-cuda.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="slang-emit-glsl-extension-tracker.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="slang-emit-glsl.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -326,6 +323,9 @@ <ClCompile Include="slang-file-system.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slang-glsl-extension-tracker.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="slang-hlsl-intrinsic-set.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -398,6 +398,9 @@ <ClCompile Include="slang-ir-validate.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slang-ir-wrap-structured-buffers.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="slang-ir.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -464,9 +467,6 @@ <ClCompile Include="slang.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="slang-ir-wrap-structured-buffers.cpp"> - <Filter>Source Files</Filter> - </ClCompile> </ItemGroup> <ItemGroup> <None Include="..\core\core.natvis"> |
