summaryrefslogtreecommitdiffstats
path: root/tools/render-test/render-test-main.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-08-21 16:04:42 -0400
committerGitHub <noreply@github.com>2020-08-21 13:04:42 -0700
commitfcac02e405661de311b5ceebbd6d3e2c78bf8aea (patch)
tree6e79865b39f0739d2ac9c3f91cc4129c244b6977 /tools/render-test/render-test-main.cpp
parent49067fd2e97b40649df3fa2ce096f78c2e45da5a (diff)
Vulkan update/NVAPI support (#1511)
* First pass at incorporating nvapi into test harness. * D3d12 Atomic Float Add via NVAPI working * Dx12 atomic float appears to work. * Atomic float add on Dx12. * Added atomic64 feature addition to vk. Fix correct output for atomic-float-byte-address.slang * Disable atomic float failing tests. * Upgraded VK headers. * Detect atomic float availability on VK. * Try to get test working for in64 atomic. * Made HLSL prelude controlled via the render-test requirements. * Added -enable-nvapi to premake. * Fix D3D12Renderer when NVAPI is not available. * Small improvements to VKRenderer. * Improve atomic documentation in target-compatibility.md.
Diffstat (limited to 'tools/render-test/render-test-main.cpp')
-rw-r--r--tools/render-test/render-test-main.cpp152
1 files changed, 104 insertions, 48 deletions
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();