summaryrefslogtreecommitdiff
path: root/tools/gfx-unit-test/get-shared-handle.cpp
diff options
context:
space:
mode:
authorlucy96chen <47800040+lucy96chen@users.noreply.github.com>2021-11-12 15:43:23 -0800
committerGitHub <noreply@github.com>2021-11-12 15:43:23 -0800
commit7a4f08ee0411220c728bf42832d98e72d72167e2 (patch)
treef06410fecfe8aff8f28c913fe8cef90caa7479d1 /tools/gfx-unit-test/get-shared-handle.cpp
parent6f523dd95d1f16003c7ed1d4a9e1da0cba0ea76c (diff)
Add support for buffer sharing from Vulkan to CUDA (#2008)
* Added getSharedHandle() and additional code to handle shareable buffer creation to Buffer::init() and initVulkanInstanceAndDevice() for Vulkan; Modified createBufferFromSharedHandle() in CUDA to assign externalMemoryHandleDesc.type based on the type of handle being provided; Added an additional test case to get-shared-handle.cpp testing Vulkan to CUDA * Added createBufferFromNativeHandle() to Vulkan and enabled corresponding test * disable cuda * Fixed getSharedHandle() for D3D12 buffers assigning Win32 as the handle's source * Removed a dangling comment inside Buffer::init() * Added a missing override; Added code to check that a physical device supports the necessary external memory extensions before adding them to the deviceExtensions list; Added #if SLANG_WINDOWS_FAMILY guards around all Windows-specific code and sharedHandleVulkanToCUDA test (which uses said platform-specific code) * Added Windows check around vkGetMemoryWin32HandleKHR in vk-api.h * Added missing Windows check around BufferResourceImpl destructor * Added a temporary hack to ensure synchronization between devices, which solves an issue with buffer sharing resulting in incorrect values being read back; Added #if SLANG_WIN64 around all CUDA tests as the backend currently only supports running CUDA on 64-bit (despite devices being created successfully in a 32-bit config)
Diffstat (limited to 'tools/gfx-unit-test/get-shared-handle.cpp')
-rw-r--r--tools/gfx-unit-test/get-shared-handle.cpp63
1 files changed, 61 insertions, 2 deletions
diff --git a/tools/gfx-unit-test/get-shared-handle.cpp b/tools/gfx-unit-test/get-shared-handle.cpp
index 7c091abc8..06114f139 100644
--- a/tools/gfx-unit-test/get-shared-handle.cpp
+++ b/tools/gfx-unit-test/get-shared-handle.cpp
@@ -11,6 +11,8 @@ namespace gfx_test
{
void sharedHandleTestImpl(IDevice* srcDevice, IDevice* dstDevice, UnitTestContext* context)
{
+ // Create a shareable buffer using srcDevice, get its handle, then create a buffer using the handle using
+ // dstDevice. Read back the buffer and check that its contents are correct.
const int numberCount = 4;
float initialData[] = { 0.0f, 1.0f, 2.0f, 3.0f };
IBufferResource::Desc bufferDesc = {};
@@ -36,6 +38,9 @@ namespace gfx_test
GFX_CHECK_CALL_ABORT(srcBuffer->getSharedHandle(&sharedHandle));
ComPtr<IBufferResource> dstBuffer;
GFX_CHECK_CALL_ABORT(dstDevice->createBufferFromSharedHandle(sharedHandle, bufferDesc, dstBuffer.writeRef()));
+ // Reading back the buffer from srcDevice to make sure it's been filled in before reading anything back from dstDevice
+ // TODO: Implement actual synchronization (and not this hacky solution)
+ compareComputeResult(srcDevice, srcBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
InteropHandle testHandle;
GFX_CHECK_CALL_ABORT(dstBuffer->getNativeResourceHandle(&testHandle));
@@ -43,6 +48,54 @@ namespace gfx_test
SLANG_CHECK(testDesc->elementSize == sizeof(float));
SLANG_CHECK(testDesc->sizeInBytes == numberCount * sizeof(float));
compareComputeResult(dstDevice, dstBuffer, Slang::makeArray<float>(0.0f, 1.0f, 2.0f, 3.0f));
+
+ // Check that dstBuffer can be successfully used in a compute dispatch using dstDevice.
+ Slang::ComPtr<ITransientResourceHeap> transientHeap;
+ ITransientResourceHeap::Desc transientHeapDesc = {};
+ transientHeapDesc.constantBufferSize = 4096;
+ GFX_CHECK_CALL_ABORT(
+ dstDevice->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef()));
+
+ ComPtr<IShaderProgram> shaderProgram;
+ slang::ProgramLayout* slangReflection;
+ GFX_CHECK_CALL_ABORT(loadComputeProgram(dstDevice, shaderProgram, "compute-trivial", "computeMain", slangReflection));
+
+ ComputePipelineStateDesc pipelineDesc = {};
+ pipelineDesc.program = shaderProgram.get();
+ ComPtr<gfx::IPipelineState> pipelineState;
+ GFX_CHECK_CALL_ABORT(
+ dstDevice->createComputePipelineState(pipelineDesc, pipelineState.writeRef()));
+
+ ComPtr<IResourceView> bufferView;
+ IResourceView::Desc viewDesc = {};
+ viewDesc.type = IResourceView::Type::UnorderedAccess;
+ viewDesc.format = Format::Unknown;
+ GFX_CHECK_CALL_ABORT(dstDevice->createBufferView(dstBuffer, viewDesc, bufferView.writeRef()));
+
+ {
+ ICommandQueue::Desc queueDesc = { ICommandQueue::QueueType::Graphics };
+ auto queue = dstDevice->createCommandQueue(queueDesc);
+
+ auto commandBuffer = transientHeap->createCommandBuffer();
+ auto encoder = commandBuffer->encodeComputeCommands();
+
+ auto rootObject = encoder->bindPipeline(pipelineState);
+
+ ShaderCursor rootCursor(rootObject);
+ // Bind buffer view to the entry point.
+ rootCursor.getPath("buffer").setResource(bufferView);
+
+ encoder->dispatchCompute(1, 1, 1);
+ encoder->endEncoding();
+ commandBuffer->close();
+ queue->executeCommandBuffer(commandBuffer);
+ queue->wait();
+ }
+
+ compareComputeResult(
+ dstDevice,
+ dstBuffer,
+ Slang::makeArray<float>(1.0f, 2.0f, 3.0f, 4.0f));
}
void sharedHandleTestAPI(UnitTestContext* context, Slang::RenderApiFlag::Enum srcApi, Slang::RenderApiFlag::Enum dstApi)
@@ -56,11 +109,17 @@ namespace gfx_test
sharedHandleTestImpl(srcDevice, dstDevice, context);
}
-#if 0
- // Temporarily disabled due to inconsistent test results on TC
+#if SLANG_WIN64
SLANG_UNIT_TEST(sharedHandleD3D12ToCUDA)
{
sharedHandleTestAPI(unitTestContext, Slang::RenderApiFlag::D3D12, Slang::RenderApiFlag::CUDA);
}
+
+#if SLANG_WINDOWS_FAMILY // TODO: Remove when Linux support is added
+ SLANG_UNIT_TEST(sharedHandleVulkanToCUDA)
+ {
+ sharedHandleTestAPI(unitTestContext, Slang::RenderApiFlag::Vulkan, Slang::RenderApiFlag::CUDA);
+ }
+#endif
#endif
}