summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/visual-studio/gfx/gfx.vcxproj1
-rw-r--r--build/visual-studio/gfx/gfx.vcxproj.filters3
-rw-r--r--examples/hello-world/main.cpp71
-rw-r--r--examples/shader-toy/main.cpp49
-rw-r--r--tools/gfx/cuda/render-cuda.cpp11
-rw-r--r--tools/gfx/d3d11/render-d3d11.cpp2
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp3
-rw-r--r--tools/gfx/open-gl/render-gl.cpp2
-rw-r--r--tools/gfx/render-graphics-common.cpp7
-rw-r--r--tools/gfx/render-graphics-common.h5
-rw-r--r--tools/gfx/render.h38
-rw-r--r--tools/gfx/slang-context.h43
-rw-r--r--tools/gfx/vulkan/render-vk.cpp2
-rw-r--r--tools/render-test/render-test-main.cpp2
14 files changed, 124 insertions, 115 deletions
diff --git a/build/visual-studio/gfx/gfx.vcxproj b/build/visual-studio/gfx/gfx.vcxproj
index 0ed5ed233..09555f45c 100644
--- a/build/visual-studio/gfx/gfx.vcxproj
+++ b/build/visual-studio/gfx/gfx.vcxproj
@@ -193,6 +193,7 @@
<ClInclude Include="..\..\..\tools\gfx\render-graphics-common.h" />
<ClInclude Include="..\..\..\tools\gfx\render.h" />
<ClInclude Include="..\..\..\tools\gfx\renderer-shared.h" />
+ <ClInclude Include="..\..\..\tools\gfx\slang-context.h" />
<ClInclude Include="..\..\..\tools\gfx\vulkan\render-vk.h" />
<ClInclude Include="..\..\..\tools\gfx\vulkan\vk-api.h" />
<ClInclude Include="..\..\..\tools\gfx\vulkan\vk-device-queue.h" />
diff --git a/build/visual-studio/gfx/gfx.vcxproj.filters b/build/visual-studio/gfx/gfx.vcxproj.filters
index 97658fffa..d034fc847 100644
--- a/build/visual-studio/gfx/gfx.vcxproj.filters
+++ b/build/visual-studio/gfx/gfx.vcxproj.filters
@@ -51,6 +51,9 @@
<ClInclude Include="..\..\..\tools\gfx\renderer-shared.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\tools\gfx\slang-context.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\tools\gfx\vulkan\render-vk.h">
<Filter>Header Files</Filter>
</ClInclude>
diff --git a/examples/hello-world/main.cpp b/examples/hello-world/main.cpp
index cdd998e35..e8e3c45e0 100644
--- a/examples/hello-world/main.cpp
+++ b/examples/hello-world/main.cpp
@@ -65,24 +65,6 @@ static const Vertex kVertexData[kVertexCount] =
struct HelloWorld
{
-// We will start with the code related to loading and using the Slang compiler.
-//
-// Applications interact with the Slang compiler through a "session" object.
-// There are actually two types of session:
-//
-// * The *global session* represents a loaded instance of the Slang library
-// (e.g., `slang.dll` and is used to scope allocations/resources that are
-// truly global across all compiles, such as the Slang "standard library")
-//
-// * A *session* is used to scope one or more compile actions such as
-// loading modules, generating code, and performing reflection.
-//
-// For our simple application, we will allocate a single session that is used
-// for all compilation.
-//
-ComPtr<slang::IGlobalSession> slangGlobalSession;
-ComPtr<slang::ISession> slangSession;
-
// Many Slang API functions return detailed diagnostic information
// (error messages, warnings, etc.) as a "blob" of data, or return
// a null blob pointer instead if there were no issues.
@@ -108,56 +90,15 @@ gfx::Result loadShaderProgram(
gfx::IRenderer* renderer,
gfx::IShaderProgram** outProgram)
{
- // The first step in interacting with the Slang API is to create a "global session,"
- // which represents an instance of the Slang API loaded from the library.
- //
- if( !slangGlobalSession )
- {
- SLANG_RETURN_ON_FAIL(slang_createGlobalSession(SLANG_API_VERSION, slangGlobalSession.writeRef()));
- }
-
- // Next, we need to create a compilation session (`slang::ISession`) that will provide
+ // We need to obatin a compilation session (`slang::ISession`) that will provide
// a scope to all the compilation and loading of code we do.
//
- // In an application like this, which doesn't make use of preprocessor-based specialization,
- // we can create a single session and use it for the duration of the application.
- // One important service the session provides is re-use of modules that have already
- // been compiled, so that if two Slang files `import` the same module, the compiler
- // will only load and check that module once.
- //
- if( !slangSession )
- {
- // When creating a session we need to tell it what code generation targets we may
- // want code generated for. It is valid to have zero or more targets, but many
- // applications will only want one, corresponding to the graphics API they plan to use.
- // This application is currently hard-coded to use D3D11, so we set up for compilation
- // to DX bytecode.
- //
- // Note: the `TargetDesc` can also be used to set things like optimization settings
- // for each target, but this application doesn't care to set any of that stuff.
- //
- slang::TargetDesc targetDesc = {};
- targetDesc.format = SLANG_DXBC;
- targetDesc.profile = spFindProfile(slangGlobalSession, "sm_4_0");
-
- // The session can be set up with a few other options, notably:
- //
- // * Any search paths that should be used when resolving `import` or `#include` directives.
- //
- // * Any preprocessor macros to pre-define when reading in files.
- //
- // This application doesn't plan to make heavy use of the preprocessor, and all its
- // shader files are in the same directory, so we just use the default options (which
- // will lead to the only search path being the current working directory).
- //
- slang::SessionDesc sessionDesc = {};
- sessionDesc.targetCount = 1;
- sessionDesc.targets = &targetDesc;
-
- SLANG_RETURN_ON_FAIL(slangGlobalSession->createSession(sessionDesc, slangSession.writeRef()));
- }
+ // Our example application uses the `gfx` graphics API abstraction layer, which already
+ // creates a Slang compilation session for us, so we just grab and use it here.
+ ComPtr<slang::ISession> slangSession;
+ slangSession = renderer->getSlangSession();
- // Once the session has been created, we can start loading code into it.
+ // We can now start loading code into the slang session.
//
// The simplest way to load code is by calling `loadModule` with the name of a Slang
// module. A call to `loadModule("MyStuff")` will behave more or less as if you
diff --git a/examples/shader-toy/main.cpp b/examples/shader-toy/main.cpp
index 044c1805b..a1408e38e 100644
--- a/examples/shader-toy/main.cpp
+++ b/examples/shader-toy/main.cpp
@@ -91,52 +91,15 @@ void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob)
//
Result loadShaderProgram(gfx::IRenderer* renderer, ComPtr<gfx::IShaderProgram>& outShaderProgram)
{
- // The first step in interacting with the Slang API is to create a "global session,"
- // which represents an instance of the Slang API loaded from the library.
- //
- ComPtr<slang::IGlobalSession> slangGlobalSession;
- SLANG_RETURN_ON_FAIL(slang_createGlobalSession(SLANG_API_VERSION, slangGlobalSession.writeRef()));
-
- // Next, we need to create a compilation session (`slang::ISession`) that will provide
+ // We need to obatin a compilation session (`slang::ISession`) that will provide
// a scope to all the compilation and loading of code we do.
//
- // In an application like this, which doesn't make use of preprocessor-based specialization,
- // we can create a single session and use it for the duration of the application.
- // One important service the session provides is re-use of modules that have already
- // been compiled, so that if two Slang files `import` the same module, the compiler
- // will only load and check that module once.
- //
- // When creating a session we need to tell it what code generation targets we may
- // want code generated for. It is valid to have zero or more targets, but many
- // applications will only want one, corresponding to the graphics API they plan to use.
- // This application is currently hard-coded to use D3D11, so we set up for compilation
- // to DX bytecode.
- //
- // Note: the `TargetDesc` can also be used to set things like optimization settings
- // for each target, but this application doesn't care to set any of that stuff.
- //
- slang::TargetDesc targetDesc = {};
- targetDesc.format = SLANG_DXBC;
- targetDesc.profile = spFindProfile(slangGlobalSession, "sm_4_0");
-
- // The session can be set up with a few other options, notably:
- //
- // * Any search paths that should be used when resolving `import` or `#include` directives.
- //
- // * Any preprocessor macros to pre-define when reading in files.
- //
- // This application doesn't plan to make heavy use of the preprocessor, and all its
- // shader files are in the same directory, so we just use the default options (which
- // will lead to the only search path being the current working directory).
- //
- slang::SessionDesc sessionDesc = {};
- sessionDesc.targetCount = 1;
- sessionDesc.targets = &targetDesc;
-
+ // Our example application uses the `gfx` graphics API abstraction layer, which already
+ // creates a Slang compilation session for us, so we just grab and use it here.
ComPtr<slang::ISession> slangSession;
- SLANG_RETURN_ON_FAIL(slangGlobalSession->createSession(sessionDesc, slangSession.writeRef()));
-
- // Once the session has been created, we can start loading code into it.
+ SLANG_RETURN_ON_FAIL(renderer->getSlangSession(slangSession.writeRef()));
+
+ // Once the session has been obtained, we can start loading code into it.
//
// The simplest way to load code is by calling `loadModule` with the name of a Slang
// module. A call to `loadModule("MyStuff")` will behave more or less as if you
diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp
index d1e320224..057674550 100644
--- a/tools/gfx/cuda/render-cuda.cpp
+++ b/tools/gfx/cuda/render-cuda.cpp
@@ -6,6 +6,7 @@
#include "../renderer-shared.h"
#include "../render-graphics-common.h"
+#include "../slang-context.h"
#ifdef GFX_ENABLE_CUDA
#include <cuda.h>
@@ -782,6 +783,7 @@ private:
CUcontext m_context = nullptr;
CUDAPipelineState* currentPipeline = nullptr;
CUDARootShaderObject* currentRootObject = nullptr;
+ SlangContext slangContext;
public:
~CUDARenderer()
{
@@ -792,6 +794,8 @@ private:
}
virtual SLANG_NO_THROW SlangResult SLANG_MCALL initialize(const Desc& desc, void* inWindowHandle) override
{
+ SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_PTX, "sm_5_1"));
+
SLANG_RETURN_ON_FAIL(_initCuda(reportType));
SLANG_RETURN_ON_FAIL(_findMaxFlopsDeviceIndex(&m_deviceIndex));
@@ -809,6 +813,13 @@ private:
return SLANG_OK;
}
+ virtual SLANG_NO_THROW Result SLANG_MCALL getSlangSession(slang::ISession** outSlangSession) override
+ {
+ *outSlangSession = slangContext.session.get();
+ slangContext.session->addRef();
+ return SLANG_OK;
+ }
+
virtual SLANG_NO_THROW Result SLANG_MCALL createTextureResource(
IResource::Usage initialUsage,
const ITextureResource::Desc& desc,
diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp
index 40e617a1f..3df5e25bc 100644
--- a/tools/gfx/d3d11/render-d3d11.cpp
+++ b/tools/gfx/d3d11/render-d3d11.cpp
@@ -664,6 +664,8 @@ static bool _isSupportedNVAPIOp(IUnknown* dev, uint32_t op)
SlangResult D3D11Renderer::initialize(const Desc& desc, void* inWindowHandle)
{
+ SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_DXBC, "sm_5_0"));
+
auto windowHandle = (HWND)inWindowHandle;
m_desc = desc;
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp
index 648fc3052..407f0dbf2 100644
--- a/tools/gfx/d3d12/render-d3d12.cpp
+++ b/tools/gfx/d3d12/render-d3d12.cpp
@@ -1348,7 +1348,10 @@ static bool _isSupportedNVAPIOp(ID3D12Device* dev, uint32_t op)
Result D3D12Renderer::initialize(const Desc& desc, void* inWindowHandle)
{
+ SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_DXBC, "sm_5_1"));
+
m_hwnd = (HWND)inWindowHandle;
+
// Rather than statically link against D3D, we load it dynamically.
HMODULE d3dModule = LoadLibraryA("d3d12.dll");
diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp
index 49fd6b005..80edbdceb 100644
--- a/tools/gfx/open-gl/render-gl.cpp
+++ b/tools/gfx/open-gl/render-gl.cpp
@@ -785,6 +785,8 @@ void GLRenderer::destroyBindingEntries(const BindingState::Desc& desc, const Bin
SLANG_NO_THROW Result SLANG_MCALL GLRenderer::initialize(const Desc& desc, void* inWindowHandle)
{
+ SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_GLSL, "sm_5_0"));
+
auto windowHandle = (HWND)inWindowHandle;
m_desc = desc;
diff --git a/tools/gfx/render-graphics-common.cpp b/tools/gfx/render-graphics-common.cpp
index 593d4708c..adc943d1d 100644
--- a/tools/gfx/render-graphics-common.cpp
+++ b/tools/gfx/render-graphics-common.cpp
@@ -1372,6 +1372,13 @@ SLANG_NO_THROW bool SLANG_MCALL gfx::GraphicsAPIRenderer::hasFeature(const char*
return m_features.findFirstIndex([&](Slang::String x) { return x == featureName; }) != -1;
}
+SLANG_NO_THROW Result SLANG_MCALL gfx::GraphicsAPIRenderer::getSlangSession(slang::ISession** outSlangSession)
+{
+ *outSlangSession = slangContext.session.get();
+ slangContext.session->addRef();
+ return SLANG_OK;
+}
+
GraphicsCommonShaderProgram::~GraphicsCommonShaderProgram()
{
// Note: It might not seem like this destructor is needed at all, since
diff --git a/tools/gfx/render-graphics-common.h b/tools/gfx/render-graphics-common.h
index 3a07f2993..f4d9567e3 100644
--- a/tools/gfx/render-graphics-common.h
+++ b/tools/gfx/render-graphics-common.h
@@ -2,9 +2,11 @@
#include "tools/gfx/render.h"
#include "core/slang-basic.h"
+#include "tools/gfx/slang-context.h"
namespace gfx
{
+
class GraphicsCommonProgramLayout;
class GraphicsCommonShaderProgram : public IShaderProgram, public Slang::RefObject
@@ -32,6 +34,8 @@ public:
virtual SLANG_NO_THROW Result SLANG_MCALL getFeatures(
const char** outFeatures, UInt bufferSize, UInt* outFeatureCount) SLANG_OVERRIDE;
virtual SLANG_NO_THROW bool SLANG_MCALL hasFeature(const char* featureName) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW Result SLANG_MCALL getSlangSession(slang::ISession** outSlangSession) SLANG_OVERRIDE;
+
virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObjectLayout(
slang::TypeLayoutReflection* typeLayout, IShaderObjectLayout** outLayout) SLANG_OVERRIDE;
virtual SLANG_NO_THROW Result SLANG_MCALL
@@ -51,6 +55,7 @@ public:
protected:
Slang::List<Slang::String> m_features;
+ SlangContext slangContext;
};
struct GfxGUID
diff --git a/tools/gfx/render.h b/tools/gfx/render.h
index 4c3b71645..325bab4ee 100644
--- a/tools/gfx/render.h
+++ b/tools/gfx/render.h
@@ -1085,15 +1085,32 @@ struct Viewport
class IRenderer: public ISlangUnknown
{
public:
+ struct SlangDesc
+ {
+ slang::IGlobalSession* slangGlobalSession = nullptr; // (optional) A slang global session object. If null will create automatically.
+
+ SlangMatrixLayoutMode defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_ROW_MAJOR;
+
+ char const* const* searchPaths = nullptr;
+ SlangInt searchPathCount = 0;
+
+ slang::PreprocessorMacroDesc const* preprocessorMacros = nullptr;
+ SlangInt preprocessorMacroCount = 0;
+
+ const char* targetProfile = nullptr; // (optional) Target shader profile. If null this will be set to platform dependent default.
+ SlangFloatingPointMode floatingPointMode = SLANG_FLOATING_POINT_MODE_DEFAULT;
+ SlangOptimizationLevel optimizationLevel = SLANG_OPTIMIZATION_LEVEL_DEFAULT;
+ };
struct Desc
{
- int width = 0; ///< Width in pixels
- int height = 0; ///< height in pixels
- const char* adapter = nullptr; ///< Name to identify the adapter to use
- int requiredFeatureCount = 0; ///< Number of required features.
- const char** requiredFeatures = nullptr; ///< Array of required feature names, whose size is `requiredFeatureCount`.
- int nvapiExtnSlot = -1; ///< The slot (typically UAV) used to identify NVAPI intrinsics. If >=0 NVAPI is required.
+ int width = 0; // Width in pixels
+ int height = 0; // height in pixels
+ const char* adapter = nullptr; // Name to identify the adapter to use
+ int requiredFeatureCount = 0; // Number of required features.
+ const char** requiredFeatures = nullptr; // Array of required feature names, whose size is `requiredFeatureCount`.
+ int nvapiExtnSlot = -1; // The slot (typically UAV) used to identify NVAPI intrinsics. If >=0 NVAPI is required.
+ SlangDesc slang = {}; // Configurations for Slang.
};
// Will return with SLANG_E_NOT_AVAILABLE if NVAPI can't be initialized and nvapiExtnSlot >= 0
@@ -1104,6 +1121,15 @@ public:
/// Returns a list of features supported by the renderer.
virtual SLANG_NO_THROW Result SLANG_MCALL getFeatures(const char** outFeatures, UInt bufferSize, UInt* outFeatureCount) = 0;
+ virtual SLANG_NO_THROW Result SLANG_MCALL getSlangSession(slang::ISession** outSlangSession) = 0;
+
+ inline ComPtr<slang::ISession> getSlangSession()
+ {
+ ComPtr<slang::ISession> result;
+ getSlangSession(result.writeRef());
+ return result;
+ }
+
virtual SLANG_NO_THROW void SLANG_MCALL setClearColor(const float color[4]) = 0;
virtual SLANG_NO_THROW void SLANG_MCALL clearFrame() = 0;
diff --git a/tools/gfx/slang-context.h b/tools/gfx/slang-context.h
new file mode 100644
index 000000000..e6168deed
--- /dev/null
+++ b/tools/gfx/slang-context.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "tools/gfx/render.h"
+
+namespace gfx
+{
+ class SlangContext
+ {
+ public:
+ Slang::ComPtr<slang::IGlobalSession> globalSession;
+ Slang::ComPtr<slang::ISession> session;
+ Result initialize(const gfx::IRenderer::SlangDesc& desc, SlangCompileTarget compileTarget, const char* defaultProfileName)
+ {
+ if (desc.slangGlobalSession)
+ {
+ globalSession = desc.slangGlobalSession;
+ }
+ else
+ {
+ SLANG_RETURN_ON_FAIL(slang::createGlobalSession(globalSession.writeRef()));
+ }
+
+ slang::SessionDesc slangSessionDesc = {};
+ slangSessionDesc.defaultMatrixLayoutMode = desc.defaultMatrixLayoutMode;
+ slangSessionDesc.searchPathCount = desc.searchPathCount;
+ slangSessionDesc.searchPaths = desc.searchPaths;
+ slangSessionDesc.preprocessorMacroCount = desc.preprocessorMacroCount;
+ slangSessionDesc.preprocessorMacros = desc.preprocessorMacros;
+ slang::TargetDesc targetDesc = {};
+ targetDesc.format = compileTarget;
+ auto targetProfile = desc.targetProfile;
+ if (targetProfile == nullptr)
+ targetProfile = defaultProfileName;
+ targetDesc.profile = globalSession->findProfile(targetProfile);
+ targetDesc.optimizationLevel = desc.optimizationLevel;
+ targetDesc.floatingPointMode = desc.floatingPointMode;
+ slangSessionDesc.targetCount = 1;
+ slangSessionDesc.targets = &targetDesc;
+ SLANG_RETURN_ON_FAIL(globalSession->createSession(slangSessionDesc, session.writeRef()));
+ return SLANG_OK;
+ }
+ };
+}
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index 5afe3e3b4..21034d167 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -1033,6 +1033,8 @@ VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint(
SlangResult VKRenderer::initialize(const Desc& desc, void* inWindowHandle)
{
+ SLANG_RETURN_ON_FAIL(slangContext.initialize(desc.slang, SLANG_SPIRV, "sm_5_1"));
+
SLANG_RETURN_ON_FAIL(m_module.init());
SLANG_RETURN_ON_FAIL(m_api.initGlobalProcs(m_module));
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 6e35db639..27070154e 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -1304,7 +1304,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
desc.requiredFeatures = requiredFeatureList.getBuffer();
desc.requiredFeatureCount = (int)requiredFeatureList.getCount();
desc.nvapiExtnSlot = int(nvapiExtnSlot);
-
+ desc.slang.slangGlobalSession = session;
window = renderer_test::Window::create();
SLANG_RETURN_ON_FAIL(window->initialize(gWindowWidth, gWindowHeight));