summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/gfx/d3d11/render-d3d11.cpp101
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp74
-rw-r--r--tools/gfx/gfx.vcxproj3
-rw-r--r--tools/gfx/gfx.vcxproj.filters9
-rw-r--r--tools/gfx/nvapi/nvapi-include.h19
-rw-r--r--tools/gfx/nvapi/nvapi-util.cpp30
-rw-r--r--tools/gfx/nvapi/nvapi-util.h19
-rw-r--r--tools/gfx/open-gl/render-gl.cpp7
-rw-r--r--tools/gfx/render.h7
-rw-r--r--tools/gfx/vulkan/render-vk.cpp77
-rw-r--r--tools/render-test/options.cpp73
-rw-r--r--tools/render-test/options.h6
-rw-r--r--tools/render-test/render-test-main.cpp152
-rw-r--r--tools/render-test/slang-support.cpp6
-rw-r--r--tools/render-test/slang-support.h2
-rw-r--r--tools/slang-test/options.cpp10
-rw-r--r--tools/slang-test/options.h3
-rw-r--r--tools/slang-test/slang-test-main.cpp23
-rw-r--r--tools/slang-test/test-context.cpp6
-rw-r--r--tools/slang-test/test-context.h4
20 files changed, 479 insertions, 152 deletions
diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp
index 4eba4edaf..8eafd24b4 100644
--- a/tools/gfx/d3d11/render-d3d11.cpp
+++ b/tools/gfx/d3d11/render-d3d11.cpp
@@ -7,6 +7,7 @@
//WORKING: #include "options.h"
#include "../render.h"
#include "../d3d/d3d-util.h"
+#include "../nvapi/nvapi-util.h"
#include "../surface.h"
@@ -29,6 +30,13 @@
#include <d3d11_2.h>
#include <d3dcompiler.h>
+#ifdef GFX_NVAPI
+// NVAPI integration is desribed here
+// https://developer.nvidia.com/unlocking-gpu-intrinsics-hlsl
+
+# include "../nvapi/nvapi-include.h"
+#endif
+
// We will use the C standard library just for printing error messages.
#include <stdio.h>
@@ -52,6 +60,7 @@ public:
kMaxRTVs = 8,
};
+
// Renderer implementation
virtual SlangResult initialize(const Desc& desc, void* inWindowHandle) override;
virtual const List<String>& getFeatures() override { return m_features; }
@@ -102,6 +111,17 @@ public:
protected:
+ class ScopeNVAPI
+ {
+ public:
+ ScopeNVAPI() : m_renderer(nullptr) {}
+ SlangResult init(D3D11Renderer* renderer, Index regIndex);
+ ~ScopeNVAPI();
+
+ protected:
+ D3D11Renderer* m_renderer;
+ };
+
#if 0
struct BindingDetail
{
@@ -124,6 +144,7 @@ public:
};
#endif
+
enum class D3D11DescriptorSlotType
{
ConstantBuffer,
@@ -391,6 +412,8 @@ public:
float m_clearColor[4] = { 0, 0, 0, 0 };
List<String> m_features;
+
+ bool m_nvapi = false;
};
Renderer* createD3D11Renderer()
@@ -398,6 +421,44 @@ Renderer* createD3D11Renderer()
return new D3D11Renderer();
}
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!ScopeNVAPI !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+SlangResult D3D11Renderer::ScopeNVAPI::init(D3D11Renderer* renderer, Index regIndex)
+{
+ if (!renderer->m_nvapi)
+ {
+ // There is nothing to set as nvapi is not set
+ return SLANG_OK;
+ }
+
+#ifdef GFX_NVAPI
+ NvAPI_Status nvapiStatus = NvAPI_D3D11_SetNvShaderExtnSlot(renderer->m_device, NvU32(regIndex));
+ if (nvapiStatus != NVAPI_OK)
+ {
+ return SLANG_FAIL;
+ }
+#endif
+
+ // Record the renderer so it can be freed
+ m_renderer = renderer;
+ return SLANG_OK;
+}
+
+D3D11Renderer::ScopeNVAPI::~ScopeNVAPI()
+{
+ // If the m_renderer is not set, it must not have been set up
+ if (m_renderer)
+ {
+#ifdef GFX_NVAPI
+ // Disable the slot used
+ NvAPI_Status nvapiStatus = NvAPI_D3D11_SetNvShaderExtnSlot(m_renderer->m_device, ~0);
+ SLANG_ASSERT(nvapiStatus == NVAPI_OK);
+#endif
+ }
+}
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!D3D11Renderer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
/* static */HRESULT D3D11Renderer::captureTextureToSurface(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture, Surface& surfaceOut)
{
if (!context) return E_INVALIDARG;
@@ -585,6 +646,30 @@ SlangResult D3D11Renderer::initialize(const Desc& desc, void* inWindowHandle)
SLANG_ASSERT(m_immediateContext && m_swapChain && m_device);
}
+ // NVAPI
+ {
+ const char* features[] = { "nvapi", "atomic-float", "atomic-int64" };
+ bool needsNvapi = false;
+ for (Index i = 0; i < SLANG_COUNT_OF(features); ++i)
+ {
+ if (desc.requiredFeatures.indexOf(features[i]) >= 0)
+ {
+ needsNvapi = true;
+ break;
+ }
+ }
+
+ if (needsNvapi && SLANG_SUCCEEDED(NVAPIUtil::initialize()))
+ {
+ // TODO(JS): We should test for specific features here.
+ for (Index i = 0; i < SLANG_COUNT_OF(features); ++i)
+ {
+ m_features.add(features[i]);
+ }
+ m_nvapi = true;
+ }
+ }
+
// TODO: Add support for debugging to help detect leaks:
//
// ComPtr<ID3D11Debug> gDebug;
@@ -1505,7 +1590,12 @@ Result D3D11Renderer::createProgram(const ShaderProgram::Desc& desc, ShaderProgr
auto computeKernel = desc.findKernel(StageType::Compute);
ComPtr<ID3D11ComputeShader> computeShader;
- SLANG_RETURN_ON_FAIL(m_device->CreateComputeShader(computeKernel->codeBegin, computeKernel->getCodeSize(), nullptr, computeShader.writeRef()));
+
+ {
+ ScopeNVAPI scopeNVAPI;
+ SLANG_RETURN_ON_FAIL(scopeNVAPI.init(this, 0));
+ SLANG_RETURN_ON_FAIL(m_device->CreateComputeShader(computeKernel->codeBegin, computeKernel->getCodeSize(), nullptr, computeShader.writeRef()));
+ }
RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl();
shaderProgram->m_computeShader.swap(computeShader);
@@ -1521,8 +1611,13 @@ Result D3D11Renderer::createProgram(const ShaderProgram::Desc& desc, ShaderProgr
ComPtr<ID3D11VertexShader> vertexShader;
ComPtr<ID3D11PixelShader> pixelShader;
- SLANG_RETURN_ON_FAIL(m_device->CreateVertexShader(vertexKernel->codeBegin, vertexKernel->getCodeSize(), nullptr, vertexShader.writeRef()));
- SLANG_RETURN_ON_FAIL(m_device->CreatePixelShader(fragmentKernel->codeBegin, fragmentKernel->getCodeSize(), nullptr, pixelShader.writeRef()));
+ {
+ ScopeNVAPI scopeNVAPI;
+ SLANG_RETURN_ON_FAIL(scopeNVAPI.init(this, 0));
+
+ SLANG_RETURN_ON_FAIL(m_device->CreateVertexShader(vertexKernel->codeBegin, vertexKernel->getCodeSize(), nullptr, vertexShader.writeRef()));
+ SLANG_RETURN_ON_FAIL(m_device->CreatePixelShader(fragmentKernel->codeBegin, fragmentKernel->getCodeSize(), nullptr, pixelShader.writeRef()));
+ }
RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl();
shaderProgram->m_vertexShader.swap(vertexShader);
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp
index ba9bde63a..ca44aa04d 100644
--- a/tools/gfx/d3d12/render-d3d12.cpp
+++ b/tools/gfx/d3d12/render-d3d12.cpp
@@ -23,7 +23,16 @@
#include <dxgi1_4.h>
#include <d3d12.h>
-#include <d3dcompiler.h>
+//#include <d3dcompiler.h>
+
+#ifndef __ID3D12GraphicsCommandList1_FWD_DEFINED__
+// If can't find a definition of CommandList1, just use an empty definition
+struct ID3D12GraphicsCommandList1 {};
+#endif
+
+#ifdef GFX_NVAPI
+# include "../nvapi/nvapi-include.h"
+#endif
#include "../../slang-com-ptr.h"
#include "../flag-combiner.h"
@@ -34,6 +43,8 @@
#include "../d3d/d3d-util.h"
+#include "../nvapi/nvapi-util.h"
+
// We will use the C standard library just for printing error messages.
#include <stdio.h>
@@ -690,6 +701,8 @@ protected:
HWND m_hwnd = nullptr;
List<String> m_features;
+
+ bool m_nvapi = false;
};
Renderer* createD3D12Renderer()
@@ -1589,6 +1602,30 @@ Result D3D12Renderer::initialize(const Desc& desc, void* inWindowHandle)
return SLANG_FAIL;
}
+ // NVAPI
+ {
+ const char* features[] = { "nvapi", "atomic-float", "atomic-int64" };
+ bool needsNvapi = false;
+ for (Index i = 0; i < SLANG_COUNT_OF(features); ++i)
+ {
+ if (desc.requiredFeatures.indexOf(features[i]) >= 0)
+ {
+ needsNvapi = true;
+ break;
+ }
+ }
+
+ if (needsNvapi && SLANG_SUCCEEDED(NVAPIUtil::initialize()))
+ {
+ // TODO(JS): We should test for specific features here.
+ for (Index i = 0; i < SLANG_COUNT_OF(features); ++i)
+ {
+ m_features.add(features[i]);
+ }
+ m_nvapi = true;
+ }
+ }
+
// Set the device
m_device = m_deviceInfo.m_device;
@@ -3209,7 +3246,7 @@ void D3D12Renderer::DescriptorSetImpl::setRootConstants(
// have been a root-constant range for this call to be
// valid.
//
- SLANG_ASSERT(range < m_layout->m_ranges.getCount());
+ SLANG_ASSERT(range < UInt(m_layout->m_ranges.getCount()));
auto& rangeInfo = m_layout->m_ranges[range];
SLANG_ASSERT(rangeInfo.type == DescriptorSlotType::RootConstant);
@@ -3222,7 +3259,7 @@ void D3D12Renderer::DescriptorSetImpl::setRootConstants(
SLANG_ASSERT(rootConstantIndex >= 0);
SLANG_ASSERT(rootConstantIndex < m_layout->m_rootConstantRanges.getCount());
auto& rootConstantRangeInfo = m_layout->m_rootConstantRanges[rootConstantIndex];
- SLANG_ASSERT(offset + size <= rootConstantRangeInfo.size);
+ SLANG_ASSERT(offset + size <= UInt(rootConstantRangeInfo.size));
memcpy((char*)m_rootConstantData.getBuffer() + rootConstantRangeInfo.offset + offset, data, size);
}
@@ -3951,7 +3988,36 @@ Result D3D12Renderer::createComputePipelineState(const ComputePipelineStateDesc&
computeDesc.CS = { programImpl->m_computeShader.getBuffer(), SIZE_T(programImpl->m_computeShader.getCount()) };
ComPtr<ID3D12PipelineState> pipelineState;
- SLANG_RETURN_ON_FAIL(m_device->CreateComputePipelineState(&computeDesc, IID_PPV_ARGS(pipelineState.writeRef())));
+
+#ifdef GFX_NVAPI
+ if (m_nvapi)
+ {
+ // Also fill the extension structure.
+ // Use the same UAV slot index and register space that are declared in the shader.
+
+ // For simplicities sake we just use u0
+ NVAPI_D3D12_PSO_SET_SHADER_EXTENSION_SLOT_DESC extensionDesc;
+ extensionDesc.baseVersion = NV_PSO_EXTENSION_DESC_VER;
+ extensionDesc.version = NV_SET_SHADER_EXTENSION_SLOT_DESC_VER;
+ extensionDesc.uavSlot = 0;
+ extensionDesc.registerSpace = 0;
+
+ // Put the pointer to the extension into an array - there can be multiple extensions enabled at once.
+ const NVAPI_D3D12_PSO_EXTENSION_DESC* extensions[] = { &extensionDesc };
+
+ // Now create the PSO.
+ const NvAPI_Status nvapiStatus = NvAPI_D3D12_CreateComputePipelineState(m_device, &computeDesc, SLANG_COUNT_OF(extensions), extensions, pipelineState.writeRef());
+
+ if (nvapiStatus != NVAPI_OK)
+ {
+ return SLANG_FAIL;
+ }
+ }
+ else
+#endif
+ {
+ SLANG_RETURN_ON_FAIL(m_device->CreateComputePipelineState(&computeDesc, IID_PPV_ARGS(pipelineState.writeRef())));
+ }
RefPtr<PipelineStateImpl> pipelineStateImpl = new PipelineStateImpl();
pipelineStateImpl->m_pipelineType = PipelineType::Compute;
diff --git a/tools/gfx/gfx.vcxproj b/tools/gfx/gfx.vcxproj
index d4b1885a8..327f6d629 100644
--- a/tools/gfx/gfx.vcxproj
+++ b/tools/gfx/gfx.vcxproj
@@ -180,6 +180,8 @@
<ClInclude Include="flag-combiner.h" />
<ClInclude Include="gui.h" />
<ClInclude Include="model.h" />
+ <ClInclude Include="nvapi\nvapi-include.h" />
+ <ClInclude Include="nvapi\nvapi-util.h" />
<ClInclude Include="open-gl\render-gl.h" />
<ClInclude Include="render.h" />
<ClInclude Include="surface.h" />
@@ -202,6 +204,7 @@
<ClCompile Include="flag-combiner.cpp" />
<ClCompile Include="gui.cpp" />
<ClCompile Include="model.cpp" />
+ <ClCompile Include="nvapi\nvapi-util.cpp" />
<ClCompile Include="open-gl\render-gl.cpp" />
<ClCompile Include="render.cpp" />
<ClCompile Include="surface.cpp" />
diff --git a/tools/gfx/gfx.vcxproj.filters b/tools/gfx/gfx.vcxproj.filters
index 1c27e4f24..f5fba2295 100644
--- a/tools/gfx/gfx.vcxproj.filters
+++ b/tools/gfx/gfx.vcxproj.filters
@@ -36,6 +36,12 @@
<ClInclude Include="model.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="nvapi\nvapi-include.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="nvapi\nvapi-util.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="open-gl\render-gl.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -98,6 +104,9 @@
<ClCompile Include="model.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="nvapi\nvapi-util.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="open-gl\render-gl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/tools/gfx/nvapi/nvapi-include.h b/tools/gfx/nvapi/nvapi-include.h
new file mode 100644
index 000000000..e3674af95
--- /dev/null
+++ b/tools/gfx/nvapi/nvapi-include.h
@@ -0,0 +1,19 @@
+// nvapi-include.h
+#pragma once
+
+// A helper that makes the NVAPI available across targets
+
+#ifdef GFX_NVAPI
+// On windows if we include NVAPI, we must include windows.h first
+
+# ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <Windows.h>
+# undef WIN32_LEAN_AND_MEAN
+# undef NOMINMAX
+# endif
+
+# include <nvapi.h>
+#endif
+
diff --git a/tools/gfx/nvapi/nvapi-util.cpp b/tools/gfx/nvapi/nvapi-util.cpp
new file mode 100644
index 000000000..63bcc65fc
--- /dev/null
+++ b/tools/gfx/nvapi/nvapi-util.cpp
@@ -0,0 +1,30 @@
+#include "nvapi-util.h"
+
+#include "nvapi-include.h"
+
+namespace gfx {
+
+static SlangResult g_initStatus = SLANG_E_UNINITIALIZED;
+
+/* static */SlangResult NVAPIUtil::initialize()
+{
+#ifdef GFX_NVAPI
+ if (g_initStatus == SLANG_E_UNINITIALIZED)
+ {
+ NvAPI_Status ret = NVAPI_OK;
+ ret = NvAPI_Initialize();
+ g_initStatus = (ret == NVAPI_OK) ? SLANG_OK : SLANG_E_NOT_AVAILABLE;
+ }
+#else
+ g_initStatus = SLANG_E_NOT_AVAILABLE;
+#endif
+
+ return g_initStatus;
+}
+
+/* static */bool NVAPIUtil::isAvailable()
+{
+ return SLANG_SUCCEEDED(g_initStatus);
+}
+
+} // gfx
diff --git a/tools/gfx/nvapi/nvapi-util.h b/tools/gfx/nvapi/nvapi-util.h
new file mode 100644
index 000000000..704f4ede4
--- /dev/null
+++ b/tools/gfx/nvapi/nvapi-util.h
@@ -0,0 +1,19 @@
+// nvapi-util.h
+#pragma once
+
+#include "../../slang-com-helper.h"
+#include "../../slang-com-ptr.h"
+
+namespace gfx {
+
+struct NVAPIUtil
+{
+ /// Set up NVAPI for use. Must be called before any other function is used.
+ static SlangResult initialize();
+ /// True if the NVAPI is available, can be called even if initialize fails.
+ /// If initialize has not been called will return false
+ static bool isAvailable();
+};
+
+
+} // gfx
diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp
index ee3977a74..5f16f07bc 100644
--- a/tools/gfx/open-gl/render-gl.cpp
+++ b/tools/gfx/open-gl/render-gl.cpp
@@ -1,6 +1,8 @@
// render-gl.cpp
#include "render-gl.h"
+#include "../nvapi/nvapi-util.h"
+
//WORKING:#include "options.h"
#include "../render.h"
@@ -715,6 +717,11 @@ SlangResult GLRenderer::initialize(const Desc& desc, void* inWindowHandle)
}
}
+ if (m_desc.requiredFeatures.indexOf("nvapi") >= 0 && SLANG_SUCCEEDED(NVAPIUtil::initialize()))
+ {
+ m_features.add("nvapi");
+ }
+
auto extensions = glGetString(GL_EXTENSIONS);
// Load each of our extension functions by name
diff --git a/tools/gfx/render.h b/tools/gfx/render.h
index 051b19742..12ef1a9e9 100644
--- a/tools/gfx/render.h
+++ b/tools/gfx/render.h
@@ -800,9 +800,10 @@ public:
struct Desc
{
- int width; ///< Width in pixels
- int height; ///< height in pixels
- Slang::String adapter; ///< Name to identify the adapter to use
+ int width; ///< Width in pixels
+ int height; ///< height in pixels
+ Slang::String adapter; ///< Name to identify the adapter to use
+ Slang::List<Slang::String> requiredFeatures; ///< The features enabled on this renderer
};
virtual SlangResult initialize(const Desc& desc, void* inWindowHandle) = 0;
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index b9cc82469..28567a3b8 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -1025,31 +1025,40 @@ SlangResult VKRenderer::initialize(const Desc& desc, void* inWindowHandle)
const uint32_t majorVersion = VK_VERSION_MAJOR(basicProps.apiVersion);
const uint32_t minorVersion = VK_VERSION_MINOR(basicProps.apiVersion);
- // Float16 features
// Need in this scope because it will be linked into the device creation (if it is available)
+
+ // Float16 features
VkPhysicalDeviceFloat16Int8FeaturesKHR float16Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR };
+ // AtomicInt64 features
+ VkPhysicalDeviceShaderAtomicInt64FeaturesKHR atomicInt64Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR };
+ // Atomic Float features
+ VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomicFloatFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT };
// API version check, can't use vkGetPhysicalDeviceProperties2 yet since this device might not support it
if (VK_MAKE_VERSION(majorVersion, minorVersion, 0) >= VK_API_VERSION_1_1 &&
m_api.vkGetPhysicalDeviceProperties2 &&
m_api.vkGetPhysicalDeviceFeatures2)
{
- VkPhysicalDeviceProperties2 physicalDeviceProps2;
-
- physicalDeviceProps2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
- physicalDeviceProps2.pNext = nullptr;
- physicalDeviceProps2.properties = {};
-
- m_api.vkGetPhysicalDeviceProperties2(m_api.m_physicalDevice, &physicalDeviceProps2);
// Get device features
VkPhysicalDeviceFeatures2 deviceFeatures2 = {};
deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
- // Link together for lookup
+ // Float16
float16Features.pNext = deviceFeatures2.pNext;
deviceFeatures2.pNext = &float16Features;
+ // Atomic64
+ atomicInt64Features.pNext = deviceFeatures2.pNext;
+ deviceFeatures2.pNext = &atomicInt64Features;
+
+ // Atomic Float
+ // To detect atomic float we need
+ // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPhysicalDeviceShaderAtomicFloatFeaturesEXT.html
+
+ atomicFloatFeatures.pNext = deviceFeatures2.pNext;
+ deviceFeatures2.pNext = &atomicFloatFeatures;
+
m_api.vkGetPhysicalDeviceFeatures2(m_api.m_physicalDevice, &deviceFeatures2);
// If we have float16 features then enable
@@ -1064,7 +1073,27 @@ SlangResult VKRenderer::initialize(const Desc& desc, void* inWindowHandle)
// We have half support
m_features.add("half");
- }
+ }
+
+ if (atomicInt64Features.shaderBufferInt64Atomics)
+ {
+ // Link into the creation features
+ atomicInt64Features.pNext = (void*)deviceCreateInfo.pNext;
+ deviceCreateInfo.pNext = &atomicInt64Features;
+
+ deviceExtensions.add(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME);
+ m_features.add("atomic-int64");
+ }
+
+ if (atomicFloatFeatures.shaderBufferFloat32AtomicAdd)
+ {
+ // Link into the creation features
+ atomicFloatFeatures.pNext = (void*)deviceCreateInfo.pNext;
+ deviceCreateInfo.pNext = &atomicFloatFeatures;
+
+ deviceExtensions.add(VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME);
+ m_features.add("atomic-float");
+ }
}
int queueFamilyIndex = m_api.findQueue(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
@@ -2345,8 +2374,7 @@ Result VKRenderer::createDescriptorSetLayout(const DescriptorSetLayout::Desc& de
RefPtr<DescriptorSetLayoutImpl> descriptorSetLayoutImpl = new DescriptorSetLayoutImpl(m_api);
Slang::List<VkDescriptorSetLayoutBinding> dstBindings;
-
- uint32_t descriptorCountForTypes[VK_DESCRIPTOR_TYPE_RANGE_SIZE] = { 0, };
+ Slang::List<uint32_t> descriptorCountForTypes;
UInt rangeCount = desc.slotRangeCount;
for(UInt rr = 0; rr < rangeCount; ++rr)
@@ -2378,7 +2406,7 @@ Result VKRenderer::createDescriptorSetLayout(const DescriptorSetLayout::Desc& de
auto rootConstantRangeIndex = descriptorSetLayoutImpl->m_rootConstantRanges.getCount();
descriptorSetLayoutImpl->m_rootConstantRanges.add(rootConstantRangeInfo);
- // We will also add a `RangeInfo` to reprsent this
+ // We will also add a `RangeInfo` to represent this
// range, even though it doesn't map to a VK-level
// descriptor range.
//
@@ -2413,6 +2441,11 @@ Result VKRenderer::createDescriptorSetLayout(const DescriptorSetLayout::Desc& de
dstBinding.stageFlags = VK_SHADER_STAGE_ALL;
dstBinding.pImmutableSamplers = nullptr;
+ if (descriptorCountForTypes.getCount() <= dstDescriptorType)
+ {
+ descriptorCountForTypes.setCount(dstDescriptorType + 1);
+ }
+
descriptorCountForTypes[dstDescriptorType] += uint32_t(srcRange.count);
dstBindings.add(dstBinding);
@@ -2443,23 +2476,23 @@ Result VKRenderer::createDescriptorSetLayout(const DescriptorSetLayout::Desc& de
// Create a pool while we are at it, to allocate descriptor sets of this type.
- VkDescriptorPoolSize poolSizes[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
- uint32_t poolSizeCount = 0;
- for (int ii = 0; ii < SLANG_COUNT_OF(descriptorCountForTypes); ++ii)
+ List<VkDescriptorPoolSize> poolSizes;
+ for (Index ii = 0; ii < descriptorCountForTypes.getCount(); ++ii)
{
auto descriptorCount = descriptorCountForTypes[ii];
if (descriptorCount > 0)
{
- poolSizes[poolSizeCount].type = VkDescriptorType(ii);
- poolSizes[poolSizeCount].descriptorCount = descriptorCount;
- poolSizeCount++;
+ VkDescriptorPoolSize poolSize;
+ poolSize.type = VkDescriptorType(ii);
+ poolSize.descriptorCount = descriptorCount;
+ poolSizes.add(poolSize);
}
}
VkDescriptorPoolCreateInfo descriptorPoolInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
descriptorPoolInfo.maxSets = 128; // TODO: actually pick a size.
- descriptorPoolInfo.poolSizeCount = poolSizeCount;
- descriptorPoolInfo.pPoolSizes = &poolSizes[0];
+ descriptorPoolInfo.poolSizeCount = uint32_t(poolSizes.getCount());
+ descriptorPoolInfo.pPoolSizes = poolSizes.getBuffer();
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
SLANG_VK_CHECK(m_api.vkCreateDescriptorPool(m_device, &descriptorPoolInfo, nullptr, &descriptorPool));
@@ -2712,7 +2745,7 @@ void VKRenderer::DescriptorSetImpl::setRootConstants(
SLANG_ASSERT(rootConstantIndex >= 0);
SLANG_ASSERT(rootConstantIndex < m_layout->m_rootConstantRanges.getCount());
auto& rootConstantRangeInfo = m_layout->m_rootConstantRanges[rootConstantIndex];
- SLANG_ASSERT(offset + size <= rootConstantRangeInfo.size);
+ SLANG_ASSERT(offset + size <= UInt(rootConstantRangeInfo.size));
memcpy(m_rootConstantData.getBuffer() + rootConstantRangeInfo.offset + offset, data, size);
}
diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp
index c2afe78ac..fd4b75ed1 100644
--- a/tools/render-test/options.cpp
+++ b/tools/render-test/options.cpp
@@ -18,10 +18,6 @@
namespace renderer_test {
using namespace Slang;
-static const Options gDefaultOptions = Options();
-
-Options gOptions;
-
static gfx::RendererType _toRenderType(Slang::RenderApiType apiType)
{
using namespace Slang;
@@ -37,23 +33,22 @@ static gfx::RendererType _toRenderType(Slang::RenderApiType apiType)
}
}
-static SlangResult _setRendererType(RendererType type, const char* arg, Slang::WriterHelper stdError)
+static SlangResult _setRendererType(RendererType type, const char* arg, Slang::WriterHelper stdError, Options& ioOptions)
{
- if (gOptions.rendererType != RendererType::Unknown)
+ if (ioOptions.rendererType != RendererType::Unknown)
{
stdError.print("Already has renderer option set. Found '%s'\n", arg);
return SLANG_FAIL;
}
- gOptions.rendererType = type;
+ ioOptions.rendererType = type;
return SLANG_OK;
}
-SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper stdError)
+/* static */SlangResult Options::parse(int argc, const char*const* argv, Slang::WriterHelper stdError, Options& outOptions)
{
using namespace Slang;
- // Reset the options
- gOptions = gDefaultOptions;
+ outOptions = Options();
List<const char*> positionalArgs;
@@ -68,7 +63,7 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
// first argument is the application name
if( argCursor != argEnd )
{
- gOptions.appName = *argCursor++;
+ outOptions.appName = *argCursor++;
}
// now iterate over arguments to collect options
@@ -96,7 +91,7 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
stdError.print("expected argument for '%s' option\n", arg);
return SLANG_FAIL;
}
- gOptions.outputPath = *argCursor++;
+ outOptions.outputPath = *argCursor++;
}
else if (strcmp(arg, "-profile") == 0)
{
@@ -105,7 +100,7 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
stdError.print("expected argument for '%s' option\n", arg);
return SLANG_FAIL;
}
- gOptions.profileName = *argCursor++;
+ outOptions.profileName = *argCursor++;
}
else if (strcmp(arg, "-render-features") == 0 || strcmp(arg, "-render-feature") == 0)
{
@@ -121,7 +116,7 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
for (const auto& value : values)
{
- gOptions.renderFeatures.add(value);
+ outOptions.renderFeatures.add(value);
}
}
else if( strcmp(arg, "-xslang") == 0 )
@@ -133,36 +128,36 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
stdError.print("expected argument for '%s' option\n", arg);
return SLANG_FAIL;
}
- if( gOptions.slangArgCount == Options::kMaxSlangArgs )
+ if( outOptions.slangArgCount == Options::kMaxSlangArgs )
{
stdError.print("maximum number of '%s' options exceeded (%d)\n", arg, Options::kMaxSlangArgs);
return SLANG_FAIL;
}
- gOptions.slangArgs[gOptions.slangArgCount++] = *argCursor++;
+ outOptions.slangArgs[outOptions.slangArgCount++] = *argCursor++;
}
else if (strcmp(arg, "-compute") == 0)
{
- gOptions.shaderType = ShaderProgramType::Compute;
+ outOptions.shaderType = ShaderProgramType::Compute;
}
else if (strcmp(arg, "-graphics") == 0)
{
- gOptions.shaderType = ShaderProgramType::Graphics;
+ outOptions.shaderType = ShaderProgramType::Graphics;
}
else if (strcmp(arg, "-gcompute") == 0)
{
- gOptions.shaderType = ShaderProgramType::GraphicsCompute;
+ outOptions.shaderType = ShaderProgramType::GraphicsCompute;
}
else if (strcmp(arg, "-rt") == 0)
{
- gOptions.shaderType = ShaderProgramType::RayTracing;
+ outOptions.shaderType = ShaderProgramType::RayTracing;
}
else if( strcmp(arg, "-use-dxil") == 0 )
{
- gOptions.useDXIL = true;
+ outOptions.useDXIL = true;
}
else if (strcmp(arg, "-only-startup") == 0)
{
- gOptions.onlyStartup = true;
+ outOptions.onlyStartup = true;
}
else if (strcmp(arg, "-compile-arg") == 0)
{
@@ -175,11 +170,11 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
CommandLine::Arg arg;
arg.type = CommandLine::ArgType::Escaped;
arg.value = *argCursor++;
- gOptions.compileArgs.add(arg);
+ outOptions.compileArgs.add(arg);
}
else if (strcmp(arg, "-performance-profile") == 0)
{
- gOptions.performanceProfile = true;
+ outOptions.performanceProfile = true;
}
else if (strcmp(arg, "-adapter") == 0)
{
@@ -189,11 +184,11 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
return SLANG_FAIL;
}
- gOptions.adapter = *argCursor++;
+ outOptions.adapter = *argCursor++;
}
else if (strcmp(arg, "-output-using-type") == 0)
{
- gOptions.outputUsingType = true;
+ outOptions.outputUsingType = true;
}
else if (strcmp(arg, "-compute-dispatch") == 0)
{
@@ -220,7 +215,7 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
stdError.print("error: expected 3 comma positive integers for compute dispatch size for '%s'\n", arg);
return SLANG_FAIL;
}
- gOptions.computeDispatchSize[i] = v;
+ outOptions.computeDispatchSize[i] = v;
}
}
else if (strcmp(arg, "-source-language") == 0)
@@ -239,11 +234,21 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
return SLANG_FAIL;
}
- gOptions.sourceLanguage = sourceLanguage;
+ outOptions.sourceLanguage = sourceLanguage;
}
else if( strcmp(arg, "-no-default-entry-point") == 0 )
{
- gOptions.dontAddDefaultEntryPoints = true;
+ outOptions.dontAddDefaultEntryPoints = true;
+ }
+ else if (strcmp(arg, "-nvapi-register") == 0)
+ {
+ if (argCursor == argEnd)
+ {
+ stdError.print("error: expecting a register name for '%s'\n", arg);
+ return SLANG_FAIL;
+ }
+
+ outOptions.nvapiRegister = (*argCursor++);
}
else
{
@@ -257,7 +262,7 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
if (rendererType != RendererType::Unknown)
{
- gOptions.rendererType = rendererType;
+ outOptions.rendererType = rendererType;
continue;
}
@@ -265,8 +270,8 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
RendererType languageRenderType = _toRenderType(RenderApiUtil::findImplicitLanguageRenderApiType(argName));
if (languageRenderType != RendererType::Unknown)
{
- gOptions.targetLanguageRendererType = languageRenderType;
- gOptions.inputLanguageID = (argName == "hlsl" || argName == "glsl" || argName == "cpp" || argName == "cxx" || argName == "c") ? InputLanguageID::Native : InputLanguageID::Slang;
+ outOptions.targetLanguageRendererType = languageRenderType;
+ outOptions.inputLanguageID = (argName == "hlsl" || argName == "glsl" || argName == "cpp" || argName == "cxx" || argName == "c") ? InputLanguageID::Native : InputLanguageID::Slang;
continue;
}
}
@@ -277,12 +282,12 @@ SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper s
}
// If a render option isn't set use defaultRenderType
- gOptions.rendererType = (gOptions.rendererType == RendererType::Unknown) ? gOptions.targetLanguageRendererType : gOptions.rendererType;
+ outOptions.rendererType = (outOptions.rendererType == RendererType::Unknown) ? outOptions.targetLanguageRendererType : outOptions.rendererType;
// first positional argument is source shader path
if(positionalArgs.getCount())
{
- gOptions.sourcePath = positionalArgs[0];
+ outOptions.sourcePath = positionalArgs[0];
positionalArgs.removeAt(0);
}
diff --git a/tools/render-test/options.h b/tools/render-test/options.h
index f2f0a8ab6..d311568d4 100644
--- a/tools/render-test/options.h
+++ b/tools/render-test/options.h
@@ -74,10 +74,10 @@ struct Options
Slang::String adapter; ///< The adapter to use either name or index
uint32_t computeDispatchSize[3] = { 1, 1, 1 };
-};
-extern Options gOptions;
+ Slang::String nvapiRegister; ///< The nvapiRegister to use.
-SlangResult parseOptions(int argc, const char*const* argv, Slang::WriterHelper stdError);
+ static SlangResult parse(int argc, const char*const* argv, Slang::WriterHelper stdError, Options& outOptions);
+};
} // renderer_test
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 7efea40f9..e7356901d 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -212,7 +212,7 @@ SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer,
Result RenderTestApp::_initializeShaders(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input)
{
- SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions, input, m_compilationOutput));
+ SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, m_options, input, m_compilationOutput));
m_shaderInputLayout = m_compilationOutput.layout;
m_shaderProgram = renderer->createProgram(m_compilationOutput.output.desc);
return m_shaderProgram ? SLANG_OK : SLANG_FAIL;
@@ -368,9 +368,9 @@ Result RenderTestApp::update(Window* window)
_outputProfileTime(m_startTicks, endTicks);
}
- if (gOptions.outputPath)
+ if (m_options.outputPath)
{
- if (gOptions.shaderType == Options::ShaderProgramType::Compute || gOptions.shaderType == Options::ShaderProgramType::GraphicsCompute)
+ if (m_options.shaderType == Options::ShaderProgramType::Compute || m_options.shaderType == Options::ShaderProgramType::GraphicsCompute)
{
auto request = m_compilationOutput.output.request;
auto slangReflection = (slang::ShaderReflection*) spGetReflection(request);
@@ -379,13 +379,13 @@ Result RenderTestApp::update(Window* window)
GPULikeBindRoot bindRoot;
bindRoot.init(&bindSet, slangReflection, 0);
- BindRoot* outputBindRoot = gOptions.outputUsingType ? &bindRoot : nullptr;
+ BindRoot* outputBindRoot = m_options.outputUsingType ? &bindRoot : nullptr;
- SLANG_RETURN_ON_FAIL(writeBindingOutput(outputBindRoot, gOptions.outputPath));
+ SLANG_RETURN_ON_FAIL(writeBindingOutput(outputBindRoot, m_options.outputPath));
}
else
{
- SlangResult res = writeScreen(gOptions.outputPath);
+ SlangResult res = writeScreen(m_options.outputPath);
if (SLANG_FAILED(res))
{
fprintf(stderr, "ERROR: failed to write screen capture to file\n");
@@ -403,6 +403,33 @@ Result RenderTestApp::update(Window* window)
}
+static SlangResult _setSessionPrelude(const Options& options, const char* exePath, SlangSession* session)
+{
+ // Let's see if we need to set up special prelude for HLSL
+ if (options.nvapiRegister.getLength())
+ {
+ String rootPath;
+ SLANG_RETURN_ON_FAIL(TestToolUtil::getRootPath(exePath, rootPath));
+
+ String includePath;
+ SLANG_RETURN_ON_FAIL(TestToolUtil::getIncludePath(rootPath, "external/nvapi/nvHLSLExtns.h", includePath));
+
+ StringBuilder buf;
+ // We have to choose a slot that NVAPI will use.
+ buf << "#define NV_SHADER_EXTN_SLOT " << options.nvapiRegister << "\n";
+
+ // Include the NVAPI header
+ buf << "#include \"" << includePath << "\"\n\n";
+
+ session->setLanguagePrelude(SLANG_SOURCE_LANGUAGE_HLSL, buf.getBuffer());
+ }
+ else
+ {
+ session->setLanguagePrelude(SLANG_SOURCE_LANGUAGE_HLSL, "");
+ }
+
+ return SLANG_OK;
+}
} // namespace renderer_test
@@ -413,8 +440,10 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
StdWriters::setSingleton(stdWriters);
+ Options options;
+
// Parse command-line options
- SLANG_RETURN_ON_FAIL(parseOptions(argcIn, argvIn, StdWriters::getError()));
+ SLANG_RETURN_ON_FAIL(Options::parse(argcIn, argvIn, StdWriters::getError(), options));
// Declare window pointer before renderer, such that window is released after renderer
RefPtr<renderer_test::Window> window;
@@ -423,13 +452,13 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
input.profile = "";
input.target = SLANG_TARGET_NONE;
- input.args = &gOptions.slangArgs[0];
- input.argCount = gOptions.slangArgCount;
+ input.args = &options.slangArgs[0];
+ input.argCount = options.slangArgCount;
SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN;
SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE;
char const* profileName = "";
- switch (gOptions.rendererType)
+ switch (options.rendererType)
{
case RendererType::DirectX11:
input.target = SLANG_DXBC;
@@ -445,7 +474,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL;
slangPassThrough = SLANG_PASS_THROUGH_FXC;
- if( gOptions.useDXIL )
+ if( options.useDXIL )
{
input.target = SLANG_DXIL;
input.profile = "sm_6_0";
@@ -484,7 +513,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
return SLANG_FAIL;
}
- switch (gOptions.inputLanguageID)
+ switch (options.inputLanguageID)
{
case Options::InputLanguageID::Slang:
input.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG;
@@ -500,7 +529,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
break;
}
- switch( gOptions.shaderType )
+ switch( options.shaderType )
{
case Options::ShaderProgramType::Graphics:
case Options::ShaderProgramType::GraphicsCompute:
@@ -519,9 +548,9 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
break;
}
- if (gOptions.sourceLanguage != SLANG_SOURCE_LANGUAGE_UNKNOWN)
+ if (options.sourceLanguage != SLANG_SOURCE_LANGUAGE_UNKNOWN)
{
- input.sourceLanguage = gOptions.sourceLanguage;
+ input.sourceLanguage = options.sourceLanguage;
if (input.sourceLanguage == SLANG_SOURCE_LANGUAGE_C || input.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP)
{
@@ -530,18 +559,18 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
}
// Use the profile name set on options if set
- input.profile = gOptions.profileName ? gOptions.profileName : input.profile;
+ input.profile = options.profileName ? options.profileName : input.profile;
StringBuilder rendererName;
- rendererName << "[" << RendererUtil::toText(gOptions.rendererType) << "] ";
- if (gOptions.adapter.getLength())
+ rendererName << "[" << RendererUtil::toText(options.rendererType) << "] ";
+ if (options.adapter.getLength())
{
- rendererName << "'" << gOptions.adapter << "'";
+ rendererName << "'" << options.adapter << "'";
}
- if (gOptions.onlyStartup)
+ if (options.onlyStartup)
{
- switch (gOptions.rendererType)
+ switch (options.rendererType)
{
case RendererType::CUDA:
{
@@ -560,11 +589,27 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
}
}
+ // Let's see if we need to set up special prelude for HLSL
+ if (options.nvapiRegister.getLength())
+ {
+ // We require nvapi to be available on the device
+ if (options.renderFeatures.indexOf("nvapi") < 0)
+ {
+ options.renderFeatures.add("nvapi");
+ }
+ }
+
+ // If can't set up a necessary prelude make not available (which will lead to the test being ignored)
+ if (SLANG_FAILED(_setSessionPrelude(options, argvIn[0], session)))
+ {
+ return SLANG_E_NOT_AVAILABLE;
+ }
+
// If it's CPU testing we don't need a window or a renderer
- if (gOptions.rendererType == RendererType::CPU)
+ if (options.rendererType == RendererType::CPU)
{
// Check we have all the required features
- for (const auto& renderFeature : gOptions.renderFeatures)
+ for (const auto& renderFeature : options.renderFeatures)
{
if (!CPUComputeUtil::hasFeature(renderFeature.getUnownedSlice()))
{
@@ -573,7 +618,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
}
ShaderCompilerUtil::OutputAndLayout compilationAndLayout;
- SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions, input, compilationAndLayout));
+ SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, options, input, compilationAndLayout));
{
// Get the shared library -> it contains the executable code, we need to keep around if we recompile
@@ -586,7 +631,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
// of the test implementer to *ensure* that the straight C++ code has the same layout as the slang C++ backend.
//
// If we are running c/c++ we still need binding information, so compile again as slang source
- if (gOptions.sourceLanguage == SLANG_SOURCE_LANGUAGE_C || input.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP)
+ if (options.sourceLanguage == SLANG_SOURCE_LANGUAGE_C || input.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP)
{
ShaderCompilerUtil::Input slangInput = input;
slangInput.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG;
@@ -594,7 +639,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
// We just want CPP, so we get suitable reflection
slangInput.target = SLANG_CPP_SOURCE;
- SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions, slangInput, compilationAndLayout));
+ SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, options, slangInput, compilationAndLayout));
}
// calculate binding
@@ -603,39 +648,39 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
// Get the execution info from the lib
CPUComputeUtil::ExecuteInfo info;
- SLANG_RETURN_ON_FAIL(CPUComputeUtil::calcExecuteInfo(CPUComputeUtil::ExecuteStyle::GroupRange, sharedLibrary, gOptions.computeDispatchSize, compilationAndLayout, context, info));
+ SLANG_RETURN_ON_FAIL(CPUComputeUtil::calcExecuteInfo(CPUComputeUtil::ExecuteStyle::GroupRange, sharedLibrary, options.computeDispatchSize, compilationAndLayout, context, info));
const uint64_t startTicks = ProcessUtil::getClockTick();
SLANG_RETURN_ON_FAIL(CPUComputeUtil::execute(info));
- if (gOptions.performanceProfile)
+ if (options.performanceProfile)
{
const uint64_t endTicks = ProcessUtil::getClockTick();
_outputProfileTime(startTicks, endTicks);
}
- if (gOptions.outputPath)
+ if (options.outputPath)
{
- BindRoot* outputBindRoot = gOptions.outputUsingType ? &context.m_bindRoot : nullptr;
+ BindRoot* outputBindRoot = options.outputUsingType ? &context.m_bindRoot : nullptr;
// Dump everything out that was written
- SLANG_RETURN_ON_FAIL(ShaderInputLayout::writeBindings(outputBindRoot, compilationAndLayout.layout, context.m_buffers, gOptions.outputPath));
+ SLANG_RETURN_ON_FAIL(ShaderInputLayout::writeBindings(outputBindRoot, compilationAndLayout.layout, context.m_buffers, options.outputPath));
// Check all execution styles produce the same result
- SLANG_RETURN_ON_FAIL(CPUComputeUtil::checkStyleConsistency(sharedLibrary, gOptions.computeDispatchSize, compilationAndLayout));
+ SLANG_RETURN_ON_FAIL(CPUComputeUtil::checkStyleConsistency(sharedLibrary, options.computeDispatchSize, compilationAndLayout));
}
}
return SLANG_OK;
}
- if (gOptions.rendererType == RendererType::CUDA)
+ if (options.rendererType == RendererType::CUDA)
{
#if RENDER_TEST_CUDA
// Check we have all the required features
- for (const auto& renderFeature : gOptions.renderFeatures)
+ for (const auto& renderFeature : options.renderFeatures)
{
if (!CUDAComputeUtil::hasFeature(renderFeature.getUnownedSlice()))
{
@@ -644,25 +689,25 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
}
ShaderCompilerUtil::OutputAndLayout compilationAndLayout;
- SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions, input, compilationAndLayout));
+ SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, options, input, compilationAndLayout));
const uint64_t startTicks = ProcessUtil::getClockTick();
CUDAComputeUtil::Context context;
- SLANG_RETURN_ON_FAIL(CUDAComputeUtil::execute(compilationAndLayout, gOptions.computeDispatchSize, context));
+ SLANG_RETURN_ON_FAIL(CUDAComputeUtil::execute(compilationAndLayout, options.computeDispatchSize, context));
- if (gOptions.performanceProfile)
+ if (options.performanceProfile)
{
const uint64_t endTicks = ProcessUtil::getClockTick();
_outputProfileTime(startTicks, endTicks);
}
- if (gOptions.outputPath)
+ if (options.outputPath)
{
- BindRoot* outputBindRoot = gOptions.outputUsingType ? &context.m_bindRoot : nullptr;
+ BindRoot* outputBindRoot = options.outputUsingType ? &context.m_bindRoot : nullptr;
// Dump everything out that was written
- SLANG_RETURN_ON_FAIL(ShaderInputLayout::writeBindings(outputBindRoot, compilationAndLayout.layout, context.m_buffers, gOptions.outputPath));
+ SLANG_RETURN_ON_FAIL(ShaderInputLayout::writeBindings(outputBindRoot, compilationAndLayout.layout, context.m_buffers, options.outputPath));
}
return SLANG_OK;
@@ -671,9 +716,19 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
#endif
}
+ if (options.nvapiRegister.getLength())
+ {
+ // We require nvapi to be available on the device
+ if (options.renderFeatures.indexOf("nvapi") < 0)
+ {
+ options.renderFeatures.add("nvapi");
+ }
+ }
+
+
Slang::RefPtr<Renderer> renderer;
{
- RendererUtil::CreateFunc createFunc = RendererUtil::getCreateFunc(gOptions.rendererType);
+ RendererUtil::CreateFunc createFunc = RendererUtil::getCreateFunc(options.rendererType);
if (createFunc)
{
renderer = createFunc();
@@ -681,7 +736,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
if (!renderer)
{
- if (!gOptions.onlyStartup)
+ if (!options.onlyStartup)
{
fprintf(stderr, "Unable to create renderer %s\n", rendererName.getBuffer());
}
@@ -691,7 +746,8 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
Renderer::Desc desc;
desc.width = gWindowWidth;
desc.height = gWindowHeight;
- desc.adapter = gOptions.adapter;
+ desc.adapter = options.adapter;
+ desc.requiredFeatures = options.renderFeatures;
window = renderer_test::Window::create();
SLANG_RETURN_ON_FAIL(window->initialize(gWindowWidth, gWindowHeight));
@@ -699,14 +755,14 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
SlangResult res = renderer->initialize(desc, window->getHandle());
if (SLANG_FAILED(res))
{
- if (!gOptions.onlyStartup)
+ if (!options.onlyStartup)
{
fprintf(stderr, "Unable to initialize renderer %s\n", rendererName.getBuffer());
}
return res;
}
- for (const auto& feature : gOptions.renderFeatures)
+ for (const auto& feature : options.renderFeatures)
{
// If doesn't have required feature... we have to give up
if (!renderer->hasFeature(feature.getUnownedSlice()))
@@ -717,14 +773,14 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
}
// If the only test is we can startup, then we are done
- if (gOptions.onlyStartup)
+ if (options.onlyStartup)
{
return SLANG_OK;
}
{
RefPtr<RenderTestApp> app(new RenderTestApp);
- SLANG_RETURN_ON_FAIL(app->initialize(session, renderer, gOptions, input));
+ SLANG_RETURN_ON_FAIL(app->initialize(session, renderer, options, input));
window->show();
return window->runLoop(app);
}
@@ -758,7 +814,7 @@ int main(int argc, char** argv)
using namespace Slang;
SlangSession* session = spCreateSession(nullptr);
- TestToolUtil::setSessionDefaultPrelude(argv[0], session);
+ TestToolUtil::setSessionDefaultPreludeFromExePath(argv[0], session);
auto stdWriters = StdWriters::initDefaultSingleton();
diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp
index da6ceb010..78c730cab 100644
--- a/tools/render-test/slang-support.cpp
+++ b/tools/render-test/slang-support.cpp
@@ -50,7 +50,7 @@ static gfx::StageType _translateStage(SlangStage slangStage)
}
}
-/* static */ SlangResult ShaderCompilerUtil::compileProgram(SlangSession* session, const Input& input, const ShaderCompileRequest& request, Output& out)
+/* static */ SlangResult ShaderCompilerUtil::compileProgram(SlangSession* session, const Options& options, const Input& input, const ShaderCompileRequest& request, Output& out)
{
out.reset();
@@ -137,7 +137,7 @@ static gfx::StageType _translateStage(SlangStage slangStage)
Index explicitEntryPointCount = request.entryPoints.getCount();
for(Index ee = 0; ee < explicitEntryPointCount; ++ee)
{
- if(gOptions.dontAddDefaultEntryPoints)
+ if(options.dontAddDefaultEntryPoints)
{
// If default entry points are not to be added, then
// the `request.entryPoints` array should have been
@@ -359,7 +359,7 @@ static gfx::StageType _translateStage(SlangStage slangStage)
compileRequest.globalSpecializationArgs = layout.globalSpecializationArgs;
compileRequest.entryPointSpecializationArgs = layout.entryPointSpecializationArgs;
- return ShaderCompilerUtil::compileProgram(session, input, compileRequest, output.output);
+ return ShaderCompilerUtil::compileProgram(session, options, input, compileRequest, output.output);
}
} // renderer_test
diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h
index 99509914e..5e38c8c69 100644
--- a/tools/render-test/slang-support.h
+++ b/tools/render-test/slang-support.h
@@ -87,7 +87,7 @@ struct ShaderCompilerUtil
static SlangResult readSource(const Slang::String& inSourcePath, List<char>& outSourceText);
- static SlangResult compileProgram(SlangSession* session, const Input& input, const ShaderCompileRequest& request, Output& out);
+ static SlangResult compileProgram(SlangSession* session, const Options& options, const Input& input, const ShaderCompileRequest& request, Output& out);
};
diff --git a/tools/slang-test/options.cpp b/tools/slang-test/options.cpp
index eee099965..27b759a0e 100644
--- a/tools/slang-test/options.cpp
+++ b/tools/slang-test/options.cpp
@@ -266,16 +266,6 @@ static bool _isSubCommand(const char* arg)
return res;
}
}
- else if (strcmp(arg, "-nvapi-path") == 0)
- {
- if (argCursor == argEnd)
- {
- stdError.print("error: expected operand for '%s'\n", arg);
- return SLANG_FAIL;
- }
-
- optionsOut->nvapiPath = *argCursor++;
- }
else
{
stdError.print("unknown option '%s'\n", arg);
diff --git a/tools/slang-test/options.h b/tools/slang-test/options.h
index 220293ba0..a8c2e3852 100644
--- a/tools/slang-test/options.h
+++ b/tools/slang-test/options.h
@@ -98,9 +98,6 @@ struct Options
// The adapter to use. If empty will match first found adapter.
Slang::String adapter;
- // The path to NVAPI if available.
- Slang::String nvapiPath;
-
/// Parse the args, report any errors into stdError, and write the results into optionsOut
static SlangResult parse(int argc, char** argv, TestCategorySet* categorySet, Slang::WriterHelper stdError, Options* optionsOut);
};
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index 1144b4034..b2e2bb55c 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -495,6 +495,7 @@ Result spawnAndWaitSharedLibrary(TestContext* context, const String& testPath, c
if (options.shouldBeVerbose)
{
CommandLine testCmdLine;
+
testCmdLine.setExecutableFilename("slang-test");
if (options.binDir.getLength())
@@ -531,8 +532,10 @@ Result spawnAndWaitSharedLibrary(TestContext* context, const String& testPath, c
stdWriters.setWriter(SLANG_WRITER_CHANNEL_DIAGNOSTIC, &stdError);
}
+ String exePath = Path::combine(context->exeDirectoryPath, exeName);
+
List<const char*> args;
- args.add(exeName.getBuffer());
+ args.add(exePath.getBuffer());
for (Index i = 0; i < cmdLine.m_args.getCount(); ++i)
{
args.add(cmdLine.m_args[i].value.getBuffer());
@@ -3191,7 +3194,7 @@ SlangResult innerMain(int argc, char** argv)
// The context holds useful things used during testing
TestContext context;
- SLANG_RETURN_ON_FAIL(SLANG_FAILED(context.init()))
+ SLANG_RETURN_ON_FAIL(SLANG_FAILED(context.init(argv[0])))
auto& categorySet = context.categorySet;
@@ -3272,19 +3275,9 @@ SlangResult innerMain(int argc, char** argv)
Options& options = context.options;
- // Set up the prelude
- {
- TestToolUtil::PreludeInfo info;
- info.exePath = argv[0];
-
- if (options.nvapiPath.getLength())
- {
- info.nvapiPath = options.nvapiPath.getBuffer();
- }
-
- TestToolUtil::setSessionDefaultPrelude(info, context.getSession());
- }
-
+ // Set up the prelude/s
+ TestToolUtil::setSessionDefaultPreludeFromExePath(argv[0], context.getSession());
+
if (options.outputMode == TestOutputMode::TeamCity)
{
// On TeamCity CI there is an issue with unix/linux targets where test system may be different from the build system
diff --git a/tools/slang-test/test-context.cpp b/tools/slang-test/test-context.cpp
index 8fa5cb345..2872ddb47 100644
--- a/tools/slang-test/test-context.cpp
+++ b/tools/slang-test/test-context.cpp
@@ -5,6 +5,8 @@
#include "../../source/core/slang-string-util.h"
#include "../../source/core/slang-shared-library.h"
+#include "../../source/core/slang-test-tool-util.h"
+
#include <stdio.h>
#include <stdlib.h>
@@ -15,14 +17,14 @@ TestContext::TestContext()
m_session = nullptr;
}
-Result TestContext::init()
+Result TestContext::init(const char* exePath)
{
m_session = spCreateSession(nullptr);
if (!m_session)
{
return SLANG_FAIL;
}
-
+ SLANG_RETURN_ON_FAIL(TestToolUtil::getExeDirectoryPath(exePath, exeDirectoryPath));
return SLANG_OK;
}
diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h
index ab0a00b40..46a42f3fa 100644
--- a/tools/slang-test/test-context.h
+++ b/tools/slang-test/test-context.h
@@ -83,7 +83,7 @@ class TestContext
/// Get the slang session
SlangSession* getSession() const { return m_session; }
- SlangResult init();
+ SlangResult init(const char* exePath);
/// Get the inner main function (from shared library)
InnerMainFunc getInnerMainFunc(const Slang::String& dirPath, const Slang::String& name);
@@ -126,6 +126,8 @@ class TestContext
Slang::RefPtr<Slang::DownstreamCompilerSet> compilerSet;
+ Slang::String exeDirectoryPath;
+
protected:
struct SharedLibraryTool
{