summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-07-08 13:55:21 -0700
committerGitHub <noreply@github.com>2021-07-08 13:55:21 -0700
commitaba2731f0427a04a119a59567e6715ba4034920a (patch)
treeb5b127f776db65c7154c31a41f1e91eaeb738503 /tools
parent09950676b3f73bb9967aea183d27a30d63098475 (diff)
Allow render-test to run inline ray tracing tests. (#1903)
* Update VS projects to 2019. * Empty commit to trigger build * Implement gfx inline ray tracing on D3D12. * Allow render-test to run inline ray tracing tests. Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp16
-rw-r--r--tools/gfx/debug-layer.cpp35
-rw-r--r--tools/gfx/vulkan/render-vk.cpp1
-rw-r--r--tools/gfx/vulkan/vk-util.cpp3
-rw-r--r--tools/render-test/render-test-main.cpp220
-rw-r--r--tools/render-test/shader-input-layout.cpp6
-rw-r--r--tools/render-test/shader-input-layout.h9
7 files changed, 284 insertions, 6 deletions
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp
index 277491ccd..e85fa84a3 100644
--- a/tools/gfx/d3d12/render-d3d12.cpp
+++ b/tools/gfx/d3d12/render-d3d12.cpp
@@ -4316,6 +4316,22 @@ Result D3D12Device::initialize(const Desc& desc)
auto minPrecisionSupport = options.MinPrecisionSupport;
}
}
+ // Check ray tracing support
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS5 options;
+ if (SLANG_SUCCEEDED(m_device->CheckFeatureSupport(
+ D3D12_FEATURE_D3D12_OPTIONS5, &options, sizeof(options))))
+ {
+ if (options.RaytracingTier != D3D12_RAYTRACING_TIER_NOT_SUPPORTED)
+ {
+ m_features.add("ray-tracing");
+ }
+ if (options.RaytracingTier >= D3D12_RAYTRACING_TIER_1_1)
+ {
+ m_features.add("ray-query");
+ }
+ }
+ }
}
m_desc = desc;
diff --git a/tools/gfx/debug-layer.cpp b/tools/gfx/debug-layer.cpp
index 77dd8543e..61ec856e9 100644
--- a/tools/gfx/debug-layer.cpp
+++ b/tools/gfx/debug-layer.cpp
@@ -228,7 +228,7 @@ void validateAccelerationStructureBuildInputs(
default:
GFX_DIAGNOSE_ERROR(
"Unsupported IAccelerationStructure::TriangleDesc::indexFormat. Valid "
- "values are R_UInt32 or R_UInt16.");
+ "values are Unknown, R_UInt32 or R_UInt16.");
}
if (!buildInputs.geometryDescs[i].content.triangles.indexData)
{
@@ -237,6 +237,39 @@ void validateAccelerationStructureBuildInputs(
"IAccelerationStructure::TriangleDesc::indexCount is not 0");
}
}
+ if (buildInputs.geometryDescs[i].content.triangles.indexFormat != Format::Unknown)
+ {
+ if (buildInputs.geometryDescs[i].content.triangles.indexCount == 0)
+ {
+ GFX_DIAGNOSE_ERROR(
+ "IAccelerationStructure::TriangleDesc::indexCount cannot be 0 if "
+ "IAccelerationStructure::TriangleDesc::indexFormat is not Format::Unknown");
+ }
+ if (buildInputs.geometryDescs[i].content.triangles.indexData == 0)
+ {
+ GFX_DIAGNOSE_ERROR(
+ "IAccelerationStructure::TriangleDesc::indexData cannot be null if "
+ "IAccelerationStructure::TriangleDesc::indexFormat is not "
+ "Format::Unknown");
+ }
+ }
+ else
+ {
+ if (buildInputs.geometryDescs[i].content.triangles.indexCount != 0)
+ {
+ GFX_DIAGNOSE_ERROR(
+ "IAccelerationStructure::TriangleDesc::indexCount must be 0 if "
+ "IAccelerationStructure::TriangleDesc::indexFormat is "
+ "Format::Unknown");
+ }
+ if (buildInputs.geometryDescs[i].content.triangles.indexData != 0)
+ {
+ GFX_DIAGNOSE_ERROR(
+ "IAccelerationStructure::TriangleDesc::indexData must be null if "
+ "IAccelerationStructure::TriangleDesc::indexFormat is "
+ "Format::Unknown");
+ }
+ }
if (!buildInputs.geometryDescs[i].content.triangles.vertexData)
{
GFX_DIAGNOSE_ERROR(
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index 90bd49868..0e3640d1f 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -5552,6 +5552,7 @@ Result VKDevice::initVulkanInstanceAndDevice(bool useValidationLayer)
deviceCreateInfo.pNext = &rayQueryFeatures;
deviceExtensions.add(VK_KHR_RAY_QUERY_EXTENSION_NAME);
m_features.add("ray-query");
+ m_features.add("ray-tracing");
}
if (bufferDeviceAddressFeatures.bufferDeviceAddress)
diff --git a/tools/gfx/vulkan/vk-util.cpp b/tools/gfx/vulkan/vk-util.cpp
index c138254c0..56664d9e4 100644
--- a/tools/gfx/vulkan/vk-util.cpp
+++ b/tools/gfx/vulkan/vk-util.cpp
@@ -262,6 +262,9 @@ Result AccelerationStructureBuildGeometryInfoBuilder::build(
case Format::R_UInt16:
vkGeomData.triangles.indexType = VK_INDEX_TYPE_UINT16;
break;
+ case Format::Unknown:
+ vkGeomData.triangles.indexType = VK_INDEX_TYPE_NONE_KHR;
+ break;
default:
debugCallback->handleMessage(
DebugMessageType::Error,
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 03662a480..567e0b988 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -111,6 +111,7 @@ protected:
Options::ShaderProgramType shaderType,
const ShaderCompilerUtil::Input& input);
void _initializeRenderPass();
+ void _initializeAccelerationStructure();
uint64_t m_startTicks;
@@ -129,6 +130,11 @@ protected:
ComPtr<IFramebuffer> m_framebuffer;
ComPtr<ITextureResource> m_colorBuffer;
+ ComPtr<IBufferResource> m_blasBuffer;
+ ComPtr<IAccelerationStructure> m_bottomLevelAccelerationStructure;
+ ComPtr<IBufferResource> m_tlasBuffer;
+ ComPtr<IAccelerationStructure> m_topLevelAccelerationStructure;
+
ShaderCompilerUtil::OutputAndLayout m_compilationOutput;
ShaderInputLayout m_shaderInputLayout; ///< The binding layout
@@ -143,14 +149,17 @@ struct AssignValsFromLayoutContext
IDevice* device;
ShaderOutputPlan& outputPlan;
slang::ProgramLayout* slangReflection;
+ IAccelerationStructure* accelerationStructure;
AssignValsFromLayoutContext(
IDevice* device,
ShaderOutputPlan& outputPlan,
- slang::ProgramLayout* slangReflection)
+ slang::ProgramLayout* slangReflection,
+ IAccelerationStructure* accelerationStructure)
: device(device)
, outputPlan(outputPlan)
, slangReflection(slangReflection)
+ , accelerationStructure(accelerationStructure)
{}
void maybeAddOutput(ShaderCursor const& dstCursor, ShaderInputLayout::Val* srcVal, IResource* resource)
@@ -374,6 +383,14 @@ struct AssignValsFromLayoutContext
return SLANG_OK;
}
+ SlangResult assignAccelerationStructure(
+ ShaderCursor const& dstCursor,
+ ShaderInputLayout::AccelerationStructureVal* srcVal)
+ {
+ dstCursor.setResource(accelerationStructure);
+ return SLANG_OK;
+ }
+
SlangResult assign(ShaderCursor const& dstCursor, ShaderInputLayout::ValPtr const& srcVal)
{
auto& entryCursor = dstCursor;
@@ -407,6 +424,9 @@ struct AssignValsFromLayoutContext
case ShaderInputType::Array:
return assignArray(dstCursor, (ShaderInputLayout::ArrayVal*) srcVal.Ptr());
+ case ShaderInputType::AccelerationStructure:
+ return assignAccelerationStructure(
+ dstCursor, (ShaderInputLayout::AccelerationStructureVal*)srcVal.Ptr());
default:
assert(!"Unhandled type");
return SLANG_FAIL;
@@ -419,9 +439,11 @@ SlangResult _assignVarsFromLayout(
IShaderObject* shaderObject,
ShaderInputLayout const& layout,
ShaderOutputPlan& ioOutputPlan,
- slang::ProgramLayout* slangReflection)
+ slang::ProgramLayout* slangReflection,
+ IAccelerationStructure* accelerationStructure)
{
- AssignValsFromLayoutContext context(device, ioOutputPlan, slangReflection);
+ AssignValsFromLayoutContext context(
+ device, ioOutputPlan, slangReflection, accelerationStructure);
ShaderCursor rootCursor = ShaderCursor(shaderObject);
return context.assign(rootCursor, layout.rootVal);
}
@@ -438,7 +460,12 @@ Result RenderTestApp::applyBinding(PipelineType pipelineType, ICommandEncoder* e
IComputeCommandEncoder* computeEncoder = static_cast<IComputeCommandEncoder*>(encoder);
auto rootObject = computeEncoder->bindPipeline(m_pipelineState);
SLANG_RETURN_ON_FAIL(_assignVarsFromLayout(
- m_device, rootObject, m_compilationOutput.layout, m_outputPlan, slangReflection));
+ m_device,
+ rootObject,
+ m_compilationOutput.layout,
+ m_outputPlan,
+ slangReflection,
+ m_topLevelAccelerationStructure));
}
break;
case PipelineType::Graphics:
@@ -446,7 +473,12 @@ Result RenderTestApp::applyBinding(PipelineType pipelineType, ICommandEncoder* e
IRenderCommandEncoder* renderEncoder = static_cast<IRenderCommandEncoder*>(encoder);
auto rootObject = renderEncoder->bindPipeline(m_pipelineState);
SLANG_RETURN_ON_FAIL(_assignVarsFromLayout(
- m_device, rootObject, m_compilationOutput.layout, m_outputPlan, slangReflection));
+ m_device,
+ rootObject,
+ m_compilationOutput.layout,
+ m_outputPlan,
+ slangReflection,
+ m_topLevelAccelerationStructure));
setProjectionMatrix(rootObject);
}
break;
@@ -477,6 +509,7 @@ SlangResult RenderTestApp::initialize(
m_device = device;
_initializeRenderPass();
+ _initializeAccelerationStructure();
{
switch(m_options.shaderType)
@@ -635,6 +668,183 @@ void RenderTestApp::_initializeRenderPass()
m_device->createRenderPassLayout(renderPassDesc, m_renderPass.writeRef());
}
+void RenderTestApp::_initializeAccelerationStructure()
+{
+ if (!m_device->hasFeature("ray-tracing"))
+ return;
+ IBufferResource::Desc vertexBufferDesc;
+ vertexBufferDesc.type = IResource::Type::Buffer;
+ vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex);
+ vertexBufferDesc.defaultState = ResourceState::ShaderResource;
+ ComPtr<IBufferResource> vertexBuffer =
+ m_device->createBufferResource(vertexBufferDesc, &kVertexData[0]);
+
+ IBufferResource::Desc transformBufferDesc;
+ transformBufferDesc.type = IResource::Type::Buffer;
+ transformBufferDesc.sizeInBytes = sizeof(float) * 16;
+ transformBufferDesc.defaultState = ResourceState::ShaderResource;
+ float transformData[12] = {
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
+ ComPtr<IBufferResource> transformBuffer =
+ m_device->createBufferResource(transformBufferDesc, &transformData);
+
+ // Build bottom level acceleration structure.
+ {
+ IAccelerationStructure::BuildInputs accelerationStructureBuildInputs;
+ IAccelerationStructure::PrebuildInfo accelerationStructurePrebuildInfo;
+ accelerationStructureBuildInputs.descCount = 1;
+ accelerationStructureBuildInputs.kind = IAccelerationStructure::Kind::BottomLevel;
+ accelerationStructureBuildInputs.flags =
+ IAccelerationStructure::BuildFlags::AllowCompaction;
+ IAccelerationStructure::GeometryDesc geomDesc;
+ geomDesc.flags = IAccelerationStructure::GeometryFlags::Opaque;
+ geomDesc.type = IAccelerationStructure::GeometryType::Triangles;
+ geomDesc.content.triangles.indexCount = 0;
+ geomDesc.content.triangles.indexData = 0;
+ geomDesc.content.triangles.indexFormat = Format::Unknown;
+ geomDesc.content.triangles.vertexCount = kVertexCount;
+ geomDesc.content.triangles.vertexData = vertexBuffer->getDeviceAddress();
+ geomDesc.content.triangles.vertexFormat = Format::RGB_Float32;
+ geomDesc.content.triangles.vertexStride = sizeof(Vertex);
+ geomDesc.content.triangles.transform3x4 = transformBuffer->getDeviceAddress();
+ accelerationStructureBuildInputs.geometryDescs = &geomDesc;
+
+ // Query buffer size for acceleration structure build.
+ m_device->getAccelerationStructurePrebuildInfo(
+ accelerationStructureBuildInputs, &accelerationStructurePrebuildInfo);
+ // Allocate buffers for acceleration structure.
+ IBufferResource::Desc asDraftBufferDesc;
+ asDraftBufferDesc.type = IResource::Type::Buffer;
+ asDraftBufferDesc.defaultState = ResourceState::AccelerationStructure;
+ asDraftBufferDesc.sizeInBytes = accelerationStructurePrebuildInfo.resultDataMaxSize;
+ ComPtr<IBufferResource> draftBuffer = m_device->createBufferResource(asDraftBufferDesc);
+ IBufferResource::Desc scratchBufferDesc;
+ scratchBufferDesc.type = IResource::Type::Buffer;
+ scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
+ scratchBufferDesc.sizeInBytes = accelerationStructurePrebuildInfo.scratchDataSize;
+ ComPtr<IBufferResource> scratchBuffer = m_device->createBufferResource(scratchBufferDesc);
+
+ // Build acceleration structure.
+ ComPtr<IQueryPool> compactedSizeQuery;
+ IQueryPool::Desc queryPoolDesc;
+ queryPoolDesc.count = 1;
+ queryPoolDesc.type = QueryType::AccelerationStructureCompactedSize;
+ m_device->createQueryPool(queryPoolDesc, compactedSizeQuery.writeRef());
+
+ ComPtr<IAccelerationStructure> draftAS;
+ IAccelerationStructure::CreateDesc draftCreateDesc;
+ draftCreateDesc.buffer = draftBuffer;
+ draftCreateDesc.kind = IAccelerationStructure::Kind::BottomLevel;
+ draftCreateDesc.offset = 0;
+ draftCreateDesc.size = accelerationStructurePrebuildInfo.resultDataMaxSize;
+ m_device->createAccelerationStructure(draftCreateDesc, draftAS.writeRef());
+
+ auto commandBuffer = m_transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeRayTracingCommands();
+ IAccelerationStructure::BuildDesc buildDesc = {};
+ buildDesc.dest = draftAS;
+ buildDesc.inputs = accelerationStructureBuildInputs;
+ buildDesc.scratchData = scratchBuffer->getDeviceAddress();
+ AccelerationStructureQueryDesc compactedSizeQueryDesc = {};
+ compactedSizeQueryDesc.queryPool = compactedSizeQuery;
+ compactedSizeQueryDesc.queryType = QueryType::AccelerationStructureCompactedSize;
+ encoder->buildAccelerationStructure(buildDesc, 1, &compactedSizeQueryDesc);
+ encoder->endEncoding();
+ commandBuffer->close();
+ m_queue->executeCommandBuffer(commandBuffer);
+ m_queue->wait();
+
+ uint64_t compactedSize = 0;
+ compactedSizeQuery->getResult(0, 1, &compactedSize);
+ IBufferResource::Desc asBufferDesc;
+ asBufferDesc.type = IResource::Type::Buffer;
+ asBufferDesc.defaultState = ResourceState::AccelerationStructure;
+ asBufferDesc.sizeInBytes = compactedSize;
+ m_blasBuffer = m_device->createBufferResource(asBufferDesc);
+ IAccelerationStructure::CreateDesc createDesc;
+ createDesc.buffer = m_blasBuffer;
+ createDesc.kind = IAccelerationStructure::Kind::BottomLevel;
+ createDesc.offset = 0;
+ createDesc.size = compactedSize;
+ m_device->createAccelerationStructure(createDesc, m_bottomLevelAccelerationStructure.writeRef());
+
+ commandBuffer = m_transientHeap->createCommandBuffer();
+ encoder = commandBuffer->encodeRayTracingCommands();
+ encoder->copyAccelerationStructure(
+ m_bottomLevelAccelerationStructure, draftAS, AccelerationStructureCopyMode::Compact);
+ encoder->endEncoding();
+ commandBuffer->close();
+ m_queue->executeCommandBuffer(commandBuffer);
+ m_queue->wait();
+ }
+
+ // Build top level acceleration structure.
+ {
+ List<IAccelerationStructure::InstanceDesc> instanceDescs;
+ instanceDescs.setCount(1);
+ instanceDescs[0].accelerationStructure =
+ m_bottomLevelAccelerationStructure->getDeviceAddress();
+ instanceDescs[0].flags =
+ IAccelerationStructure::GeometryInstanceFlags::TriangleFacingCullDisable;
+ instanceDescs[0].instanceContributionToHitGroupIndex = 0;
+ instanceDescs[0].instanceID = 0;
+ instanceDescs[0].instanceMask = 0xFF;
+ float transformMatrix[] = {
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
+ memcpy(&instanceDescs[0].transform[0][0], transformMatrix, sizeof(float) * 12);
+
+ IBufferResource::Desc instanceBufferDesc;
+ instanceBufferDesc.type = IResource::Type::Buffer;
+ instanceBufferDesc.sizeInBytes =
+ instanceDescs.getCount() * sizeof(IAccelerationStructure::InstanceDesc);
+ instanceBufferDesc.defaultState = ResourceState::ShaderResource;
+ ComPtr<IBufferResource> instanceBuffer =
+ m_device->createBufferResource(instanceBufferDesc, instanceDescs.getBuffer());
+
+ IAccelerationStructure::BuildInputs accelerationStructureBuildInputs = {};
+ IAccelerationStructure::PrebuildInfo accelerationStructurePrebuildInfo = {};
+ accelerationStructureBuildInputs.descCount = 1;
+ accelerationStructureBuildInputs.kind = IAccelerationStructure::Kind::TopLevel;
+ accelerationStructureBuildInputs.instanceDescs = instanceBuffer->getDeviceAddress();
+
+ // Query buffer size for acceleration structure build.
+ m_device->getAccelerationStructurePrebuildInfo(
+ accelerationStructureBuildInputs, &accelerationStructurePrebuildInfo);
+
+ IBufferResource::Desc asBufferDesc;
+ asBufferDesc.type = IResource::Type::Buffer;
+ asBufferDesc.defaultState = ResourceState::AccelerationStructure;
+ asBufferDesc.sizeInBytes = accelerationStructurePrebuildInfo.resultDataMaxSize;
+ m_tlasBuffer = m_device->createBufferResource(asBufferDesc);
+
+ IBufferResource::Desc scratchBufferDesc;
+ scratchBufferDesc.type = IResource::Type::Buffer;
+ scratchBufferDesc.defaultState = ResourceState::UnorderedAccess;
+ scratchBufferDesc.sizeInBytes = accelerationStructurePrebuildInfo.scratchDataSize;
+ ComPtr<IBufferResource> scratchBuffer = m_device->createBufferResource(scratchBufferDesc);
+
+ IAccelerationStructure::CreateDesc createDesc;
+ createDesc.buffer = m_tlasBuffer;
+ createDesc.kind = IAccelerationStructure::Kind::TopLevel;
+ createDesc.offset = 0;
+ createDesc.size = accelerationStructurePrebuildInfo.resultDataMaxSize;
+ m_device->createAccelerationStructure(
+ createDesc, m_topLevelAccelerationStructure.writeRef());
+
+ auto commandBuffer = m_transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeRayTracingCommands();
+ IAccelerationStructure::BuildDesc buildDesc = {};
+ buildDesc.dest = m_topLevelAccelerationStructure;
+ buildDesc.inputs = accelerationStructureBuildInputs;
+ buildDesc.scratchData = scratchBuffer->getDeviceAddress();
+ encoder->buildAccelerationStructure(buildDesc, 0, nullptr);
+ encoder->endEncoding();
+ commandBuffer->close();
+ m_queue->executeCommandBuffer(commandBuffer);
+ m_queue->wait();
+ }
+}
+
void RenderTestApp::setProjectionMatrix(IShaderObject* rootObject)
{
auto info = m_device->getDeviceInfo();
diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp
index c55c10d3e..2e0741cea 100644
--- a/tools/render-test/shader-input-layout.cpp
+++ b/tools/render-test/shader-input-layout.cpp
@@ -720,6 +720,12 @@ namespace renderer_test
maybeParseOptions(parser, val.Ptr());
return val;
}
+ else if (parser.AdvanceIf("AccelerationStructure"))
+ {
+ RefPtr<ShaderInputLayout::AccelerationStructureVal> val =
+ new ShaderInputLayout::AccelerationStructureVal();
+ return val;
+ }
else
{
throw ShaderInputLayoutFormatException(String("Unknown shader input type '") + word + String("' at line") + String(parser.NextToken().Position.Line));
diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h
index ed2f57370..76ebe79b3 100644
--- a/tools/render-test/shader-input-layout.h
+++ b/tools/render-test/shader-input-layout.h
@@ -23,6 +23,7 @@ enum class ShaderInputType
Object,
Aggregate,
Specialize,
+ AccelerationStructure,
};
enum class InputTextureContent
@@ -211,6 +212,14 @@ public:
Slang::RefPtr<SamplerVal> samplerVal;
};
+ class AccelerationStructureVal : public Val
+ {
+ public:
+ AccelerationStructureVal()
+ : Val(ShaderInputType::AccelerationStructure)
+ {}
+ };
+
struct Field
{
Slang::String name;