summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt31
-rw-r--r--cmake/FindOptiX.cmake16
m---------external/optix-dev0
-rw-r--r--source/compiler-core/slang-nvrtc-compiler.cpp125
-rw-r--r--tools/render-test/slang-support.cpp16
-rw-r--r--tools/slang-test/slang-test-main.cpp6
7 files changed, 139 insertions, 58 deletions
diff --git a/.gitmodules b/.gitmodules
index 0b6d96238..16c95786d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -44,3 +44,6 @@
[submodule "external/lua"]
path = external/lua
url = https://github.com/lua/lua.git
+[submodule "external/optix-dev"]
+ path = external/optix-dev
+ url = https://github.com/NVIDIA/optix-dev.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 144303fae..a57b2190c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,6 +66,21 @@ auto_option(
CUDAToolkit
"Enable CUDA tests using CUDA found in CUDA_PATH"
)
+# Check if SLANG_ENABLE_OPTIX was explicitly set by user before auto_option
+set(_SLANG_ENABLE_OPTIX_USER_SPECIFIED FALSE)
+get_property(
+ _SLANG_ENABLE_OPTIX_CACHE_TYPE
+ CACHE SLANG_ENABLE_OPTIX
+ PROPERTY TYPE
+)
+if(
+ DEFINED SLANG_ENABLE_OPTIX
+ AND NOT SLANG_ENABLE_OPTIX STREQUAL "AUTO"
+ AND _SLANG_ENABLE_OPTIX_CACHE_TYPE STREQUAL "BOOL"
+)
+ set(_SLANG_ENABLE_OPTIX_USER_SPECIFIED TRUE)
+endif()
+
auto_option(
SLANG_ENABLE_OPTIX
OptiX
@@ -350,10 +365,18 @@ if(NOT SLANG_EMBED_CORE_MODULE AND NOT SLANG_EMBED_CORE_MODULE_SOURCE)
endif()
if(SLANG_ENABLE_OPTIX AND NOT SLANG_ENABLE_CUDA)
- message(
- SEND_ERROR
- "SLANG_ENABLE_OPTIX is not supported without SLANG_ENABLE_CUDA"
- )
+ if(_SLANG_ENABLE_OPTIX_USER_SPECIFIED)
+ message(
+ SEND_ERROR
+ "SLANG_ENABLE_OPTIX is not supported without SLANG_ENABLE_CUDA"
+ )
+ else()
+ message(
+ STATUS
+ "OptiX is not supported without CUDA. Automatically disabling SLANG_ENABLE_OPTIX."
+ )
+ set(SLANG_ENABLE_OPTIX OFF)
+ endif()
endif()
if(SLANG_ENABLE_NVAPI AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
diff --git a/cmake/FindOptiX.cmake b/cmake/FindOptiX.cmake
index d036c4fef..38c64b4c8 100644
--- a/cmake/FindOptiX.cmake
+++ b/cmake/FindOptiX.cmake
@@ -1,6 +1,15 @@
set(Optix_ROOT_DIR "" CACHE PATH "Path to an installed OptiX SDK")
-if(Optix_ROOT_DIR)
+# First try the git submodule location
+find_path(
+ OptiX_INCLUDE_DIRS
+ NAMES optix.h
+ PATHS "${CMAKE_CURRENT_SOURCE_DIR}/external/optix-dev/include"
+ NO_DEFAULT_PATH
+)
+
+# If not found and a custom path is provided, try that
+if(NOT OptiX_INCLUDE_DIRS AND Optix_ROOT_DIR)
find_path(
OptiX_INCLUDE_DIRS
NAMES optix.h
@@ -8,7 +17,10 @@ if(Optix_ROOT_DIR)
PATHS "${Optix_ROOT_DIR}"
NO_DEFAULT_PATH
)
-else()
+endif()
+
+# Finally, try system paths as fallback
+if(NOT OptiX_INCLUDE_DIRS)
find_path(OptiX_INCLUDE_DIRS NAMES optix.h)
endif()
diff --git a/external/optix-dev b/external/optix-dev
new file mode 160000
+Subproject a1280c1863ff19d87f8e827468a4cc906ba9032
diff --git a/source/compiler-core/slang-nvrtc-compiler.cpp b/source/compiler-core/slang-nvrtc-compiler.cpp
index 950a1fc6e..8c39b2de4 100644
--- a/source/compiler-core/slang-nvrtc-compiler.cpp
+++ b/source/compiler-core/slang-nvrtc-compiler.cpp
@@ -140,14 +140,16 @@ protected:
SLANG_NVRTC_FUNCS(SLANG_NVTRC_MEMBER_FUNCS);
- // Holds list of paths passed in where cuda_fp16.h is found. Does *NOT* include cuda_fp16.h.
+ // Holds list of paths passed in where cuda_fp16.h is found. Does *NOT*
+ // include cuda_fp16.h.
List<String> m_cudaFp16FoundPaths;
bool m_cudaIncludeSearched = false;
// Holds location of where include (for cuda_fp16.h) is found.
String m_cudaIncludePath;
- // Holds list of paths passed in where optix.h is found. Does *NOT* include optix.h.
+ // Holds list of paths passed in where optix.h is found. Does *NOT* include
+ // optix.h.
List<String> m_optixFoundPaths;
bool m_optixIncludeSearched = false;
@@ -234,7 +236,8 @@ static SlangResult _parseNVRTCLine(
List<UnownedStringSlice> split;
if (_hasDriveLetter(line))
{
- // The drive letter has :, which confuses things, so skip that and then fix up first entry
+ // The drive letter has :, which confuses things, so skip that and then fix
+ // up first entry
UnownedStringSlice lineWithoutDrive(line.begin() + 2, line.end());
StringUtil::split(lineWithoutDrive, ':', split);
split[0] = UnownedStringSlice(line.begin(), split[0].end());
@@ -246,7 +249,8 @@ static SlangResult _parseNVRTCLine(
if (split.getCount() >= 3)
{
- // tests/cuda/cuda-compile.cu(7): warning: variable "c" is used before its value is set
+ // tests/cuda/cuda-compile.cu(7): warning: variable "c" is used before its
+ // value is set
const auto split1 = split[1].trim();
Severity severity = Severity::Unknown;
@@ -267,8 +271,8 @@ static SlangResult _parseNVRTCLine(
//
// Anything ending with " warning:" or " error:" in effect.
- // We can expand to include character after as this is split1, as must be followed by at
- // a minimum : (as the split has at least 3 parts).
+ // We can expand to include character after as this is split1, as must be
+ // followed by at a minimum : (as the split has at least 3 parts).
const UnownedStringSlice expandSplit1(split1.begin(), split1.end() + 1);
if (expandSplit1.endsWith(toSlice(" error:")))
@@ -297,12 +301,12 @@ static SlangResult _parseNVRTCLine(
return SLANG_OK;
}
- // TODO(JS): Note here if it's not possible to determine a line as being the main
- // diagnostics we fall through to it potentially being a note.
+ // TODO(JS): Note here if it's not possible to determine a line as being the
+ // main diagnostics we fall through to it potentially being a note.
//
- // That could mean a valid diagnostic (from NVRTCs point of view) is ignored/noted, because
- // this code can't parse it. Ideally that situation would lead to an error such that we can
- // detect and things will fail.
+ // That could mean a valid diagnostic (from NVRTCs point of view) is
+ // ignored/noted, because this code can't parse it. Ideally that situation
+ // would lead to an error such that we can detect and things will fail.
//
// So we might want to revisit this determination in the future.
}
@@ -320,8 +324,8 @@ static SlangResult _parseNVRTCLine(
return SLANG_OK;
}
-/* An implementation of Path::Visitor that can be used for finding NVRTC shared library
- * installations. */
+/* An implementation of Path::Visitor that can be used for finding NVRTC shared
+ * library installations. */
struct NVRTCPathVisitor : Path::Visitor
{
struct Candidate
@@ -364,7 +368,6 @@ struct NVRTCPathVisitor : Path::Visitor
}
void sortCandidates() { m_candidates.sort(_orderCandiate); }
-
#if SLANG_WINDOWS_FAMILY
SlangResult getVersion(const UnownedStringSlice& filename, SemanticVersion& outVersion)
{
@@ -392,7 +395,8 @@ struct NVRTCPathVisitor : Path::Visitor
StringUtil::split(versionSlice, '_', slices);
if (slices.getCount() >= 2)
{
- // We don't bother checking for error here, if it's not parsable, it will be 0
+ // We don't bother checking for error here, if it's not parsable, it
+ // will be 0
StringUtil::parseInt(slices[1], patch);
}
majorMinorSlice = slices[0];
@@ -420,8 +424,8 @@ struct NVRTCPathVisitor : Path::Visitor
#else
// How the path is constructed depends on platform
// https://docs.nvidia.com/cuda/nvrtc/index.html
- // TODO(JS): Handle version number depending on the platform - it's different for
- // Windows/OSX/Linux
+ // TODO(JS): Handle version number depending on the platform - it's different
+ // for Windows/OSX/Linux
SlangResult getVersion(const UnownedStringSlice& filename, SemanticVersion& outVersion)
{
SLANG_UNUSED(filename);
@@ -448,7 +452,6 @@ struct NVRTCPathVisitor : Path::Visitor
}
}
-
if (filename.getLength() >= m_prefix.getLength() &&
filename.subString(0, m_prefix.getLength())
.caseInsensitiveEquals(m_prefix.getUnownedSlice()))
@@ -460,9 +463,9 @@ struct NVRTCPathVisitor : Path::Visitor
version = SemanticVersion();
}
- // We may want to add multiple versions, if they are in different locations - as
- // there may be multiple entries in the PATH, and only one works. We'll only know
- // which works by loading
+ // We may want to add multiple versions, if they are in different
+ // locations - as there may be multiple entries in the PATH, and only
+ // one works. We'll only know which works by loading
#if 0
// We already found this version, so let's not add it again
@@ -538,8 +541,8 @@ static UnownedStringSlice _getNVRTCBaseName()
#endif
}
-// Candidates are in m_candidates list. Will be ordered from the oldest to newest (in version
-// number)
+// Candidates are in m_candidates list. Will be ordered from the oldest to
+// newest (in version number)
static SlangResult _findNVRTC(NVRTCPathVisitor& visitor)
{
// First try the instance path (if supported on platform)
@@ -583,16 +586,17 @@ static SlangResult _findNVRTC(NVRTCPathVisitor& visitor)
// We are going to search the paths in order
for (const auto& path : paths)
{
- // PATH can have the same path multiple times. If we have already searched this
- // path, we don't need to again
+ // PATH can have the same path multiple times. If we have already
+ // searched this path, we don't need to again
if (!pool.has(path))
{
pool.add(path);
Path::split(path, splitPath);
- // We could search every path, but here we restrict to paths that look like CUDA
- // installations. It's a path that contains a CUDA directory and has bin
+ // We could search every path, but here we restrict to paths that look
+ // like CUDA installations. It's a path that contains a CUDA directory
+ // and has bin
if (splitPath.indexOf("CUDA") >= 0 &&
splitPath[splitPath.getCount() - 1].caseInsensitiveEquals(
UnownedStringSlice::fromLiteral("bin")))
@@ -614,7 +618,6 @@ static SlangResult _findNVRTC(NVRTCPathVisitor& visitor)
static const UnownedStringSlice g_fp16HeaderName = UnownedStringSlice::fromLiteral("cuda_fp16.h");
static const UnownedStringSlice g_optixHeaderName = UnownedStringSlice::fromLiteral("optix.h");
-
SlangResult _findFileInIncludePath(
const String& path,
const UnownedStringSlice& filename,
@@ -651,8 +654,8 @@ SlangResult NVRTCDownstreamCompiler::_findCUDAIncludePath(String& outPath)
{
outPath = String();
- // Try looking up from a symbol. This will work as long as the nvrtc is loaded somehow from a
- // dll/sharedlibrary And the header is included from there
+ // Try looking up from a symbol. This will work as long as the nvrtc is loaded
+ // somehow from a dll/sharedlibrary And the header is included from there
{
String libPath = SharedLibraryUtils::getSharedLibraryFileName((void*)m_nvrtcCreateProgram);
if (libPath.getLength())
@@ -664,9 +667,11 @@ SlangResult NVRTCDownstreamCompiler::_findCUDAIncludePath(String& outPath)
return SLANG_OK;
}
- // See if the shared library is in the SDK, as if so we know how to find the includes
+ // See if the shared library is in the SDK, as if so we know how to find
+ // the includes
// TODO(JS):
- // This directory structure is correct for windows perhaps could be different elsewhere.
+ // This directory structure is correct for windows perhaps could be
+ // different elsewhere.
{
List<UnownedStringSlice> pathSlices;
Path::split(parentPath.getUnownedSlice(), pathSlices);
@@ -742,6 +747,32 @@ SlangResult NVRTCDownstreamCompiler::_findOptixIncludePath(String& outPath)
{
outPath = String();
+ // First try to find OptiX headers in the local external/optix-dev/include
+ // directory relative to the executable path
+ {
+ StringBuilder instancePathBuilder;
+ if (SLANG_SUCCEEDED(PlatformUtil::getInstancePath(instancePathBuilder)))
+ {
+ // Get executable path, then go up to project root
+ // instancePathBuilder already contains the bin directory path
+ // Executable is in build/Debug/bin or build/Release/bin
+ // Go up 3 levels: bin -> Debug/Release -> build -> project root
+ String binPath = instancePathBuilder;
+ String buildTypeDir = Path::getParentDirectory(binPath);
+ String buildDir = Path::getParentDirectory(buildTypeDir);
+ String projectRoot = Path::getParentDirectory(buildDir);
+
+ String localOptixPath =
+ Path::combine(Path::combine(projectRoot, "external/optix-dev"), "include");
+ String optixHeader = Path::combine(localOptixPath, g_optixHeaderName);
+
+ if (File::exists(optixHeader))
+ {
+ outPath = localOptixPath;
+ return SLANG_OK;
+ }
+ }
+ }
List<String> rootPaths;
#if SLANG_WINDOWS_FAMILY
@@ -1040,9 +1071,9 @@ SlangResult NVRTCDownstreamCompiler::compile(
cmdLine.addArg("-std=c++17");
// Disable all warnings
- // This is arguably too much - but nvrtc does not appear to have a mechanism to switch off
- // individual warnings. I tried the -Xcudafe mechanism but that does not appear to work for
- // nvrtc
+ // This is arguably too much - but nvrtc does not appear to have a mechanism
+ // to switch off individual warnings. I tried the -Xcudafe mechanism but
+ // that does not appear to work for nvrtc
cmdLine.addArg("-w");
}
@@ -1103,7 +1134,8 @@ SlangResult NVRTCDownstreamCompiler::compile(
List<const char*> headers;
List<const char*> headerIncludeNames;
- // If compiling for OptiX, we need to add the appropriate search paths to the command line.
+ // If compiling for OptiX, we need to add the appropriate search paths to the
+ // command line.
//
if (options.pipelineType == PipelineType::RayTracing)
{
@@ -1111,8 +1143,8 @@ SlangResult NVRTCDownstreamCompiler::compile(
}
// Add any compiler specific options
- // NOTE! If these clash with any previously set options (as set via other flags)
- // compilation might fail.
+ // NOTE! If these clash with any previously set options (as set via other
+ // flags) compilation might fail.
if (options.compilerSpecificArguments.count > 0)
{
for (auto compilerSpecificArg : options.compilerSpecificArguments)
@@ -1201,8 +1233,8 @@ SlangResult NVRTCDownstreamCompiler::compile(
Index lastIndex = lines.getCount();
// Look for the first blank line after this point.
- // We'll assume any information after that blank line to the end of the diagnostic
- // is compilation summary information.
+ // We'll assume any information after that blank line to the end of the
+ // diagnostic is compilation summary information.
for (Index i = lastIndex - 1; i >= 0; --i)
{
if (lines[i].getLength() == 0)
@@ -1232,7 +1264,8 @@ SlangResult NVRTCDownstreamCompiler::compile(
else if (lineRes != SLANG_E_NOT_FOUND)
{
// If there is an error exit
- // But if SLANG_E_NOT_FOUND that just means this line couldn't be parsed, so ignore.
+ // But if SLANG_E_NOT_FOUND that just means this line couldn't be
+ // parsed, so ignore.
return lineRes;
}
}
@@ -1281,8 +1314,8 @@ SlangResult NVRTCDownstreamCompiler::convert(
// PTX is 'binary like' and 'assembly like' so we allow conversion either way
// We do it by just getting as a blob and sharing that blob.
- // A more sophisticated implementation could proxy to the original artifact, but this
- // is simpler, and probably fine in most scenarios.
+ // A more sophisticated implementation could proxy to the original artifact,
+ // but this is simpler, and probably fine in most scenarios.
ComPtr<ISlangBlob> blob;
SLANG_RETURN_ON_FAIL(from->loadBlob(ArtifactKeep::Yes, blob.writeRef()));
@@ -1352,9 +1385,9 @@ static SlangResult _findAndLoadNVRTC(
// a library simply named `nvrtc` (well, `libnvrtc`) which
// is expected to match whatever the user has installed.
//
- // On Windows an installation could place the version of nvrtc it uses in the same directory
- // as the slang binary, such that it's loaded.
- // Using this name also allows a ISlangSharedLibraryLoader to easily identify what is
+ // On Windows an installation could place the version of nvrtc it uses in
+ // the same directory as the slang binary, such that it's loaded. Using this
+ // name also allows a ISlangSharedLibraryLoader to easily identify what is
// required and perhaps load a specific version
if (SLANG_FAILED(loader->loadSharedLibrary("nvrtc", library.writeRef())))
{
diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp
index f98372330..b40473d41 100644
--- a/tools/render-test/slang-support.cpp
+++ b/tools/render-test/slang-support.cpp
@@ -451,6 +451,22 @@ static SlangResult _compileProgramImpl(
specializedEntryPoints.add(specializedEntryPoint);
}
+ // If no explicit entry points were provided, check if the module has any
+ // defined entry points (e.g., functions marked with [shader(...)] attributes)
+ if (explicitEntryPointCount == 0 && !options.dontAddDefaultEntryPoints)
+ {
+ SlangInt32 definedEntryPointCount = module->getDefinedEntryPointCount();
+ for (SlangInt32 ee = 0; ee < definedEntryPointCount; ++ee)
+ {
+ ComPtr<slang::IEntryPoint> entryPoint;
+ SLANG_RETURN_ON_FAIL(module->getDefinedEntryPoint(ee, entryPoint.writeRef()));
+
+ // For now, we'll assume no specialization is needed for discovered entry points
+ // If specialization is needed, this would need to be updated
+ specializedEntryPoints.add(entryPoint);
+ }
+ }
+
if (input.passThrough == SLANG_PASS_THROUGH_NONE)
{
componentsRawPtr.add(specializedModule);
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index a5f5ee316..c22b6dbf6 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -5047,12 +5047,6 @@ SlangResult innerMain(int argc, char** argv)
options.includeCategories.add(fullTestCategory, fullTestCategory);
}
- // Don't include OptiX tests unless the client has explicit opted into them.
- if (!options.includeCategories.containsKey(optixTestCategory))
- {
- options.excludeCategories.add(optixTestCategory, optixTestCategory);
- }
-
// Exclude rendering tests when building under AppVeyor.
//
// TODO: this is very ad hoc, and we should do something cleaner.