yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Gangzheng TongConvert gfx unit tests and examples to use slang-rhi (#7577)43d0c2100

master
3.9 KiB103 linesraw
1#include "core/slang-basic.h"
2#include "gfx-test-util.h"
3#include "slang-rhi.h"
4#include "slang-rhi/shader-cursor.h"
5#include "unit-test/slang-unit-test.h"
6
7using namespace rhi;
8
9namespace gfx_test
10{
11void sharedBufferTestImpl(IDevice* srcDevice, IDevice* dstDevice, UnitTestContext* context)
12{
13    // Create a shareable buffer using srcDevice, get its handle, then create a buffer using the
14    // handle using dstDevice. Read back the buffer and check that its contents are correct.
15    const int numberCount = 4;
16    float initialData[] = {0.0f, 1.0f, 2.0f, 3.0f};
17    BufferDesc bufferDesc = {};
18    bufferDesc.size = numberCount * sizeof(float);
19    bufferDesc.format = rhi::Format::Undefined;
20    bufferDesc.elementSize = sizeof(float);
21    bufferDesc.usage = BufferUsage::ShaderResource | BufferUsage::UnorderedAccess |
22                       BufferUsage::CopySource | BufferUsage::CopyDestination | BufferUsage::Shared;
23    bufferDesc.defaultState = ResourceState::UnorderedAccess;
24    bufferDesc.memoryType = MemoryType::DeviceLocal;
25
26    ComPtr<IBuffer> srcBuffer;
27    GFX_CHECK_CALL_ABORT(
28        srcDevice->createBuffer(bufferDesc, (void*)initialData, srcBuffer.writeRef()));
29
30    NativeHandle sharedHandle;
31    GFX_CHECK_CALL_ABORT(srcBuffer->getSharedHandle(&sharedHandle));
32    ComPtr<IBuffer> dstBuffer;
33    GFX_CHECK_CALL_ABORT(
34        dstDevice->createBufferFromSharedHandle(sharedHandle, bufferDesc, dstBuffer.writeRef()));
35    // Reading back the buffer from srcDevice to make sure it's been filled in before reading
36    // anything back from dstDevice
37    // TODO: Implement actual synchronization (and not this hacky solution)
38    compareComputeResult(srcDevice, srcBuffer, std::array{0.0f, 1.0f, 2.0f, 3.0f});
39
40    NativeHandle testHandle;
41    GFX_CHECK_CALL_ABORT(dstBuffer->getNativeHandle(&testHandle));
42    const BufferDesc& testDesc = dstBuffer->getDesc();
43    SLANG_CHECK(testDesc.elementSize == sizeof(float));
44    SLANG_CHECK(testDesc.size == numberCount * sizeof(float));
45    compareComputeResult(dstDevice, dstBuffer, std::array{0.0f, 1.0f, 2.0f, 3.0f});
46
47    // Check that dstBuffer can be successfully used in a compute dispatch using dstDevice.
48    ComPtr<IShaderProgram> shaderProgram;
49    slang::ProgramLayout* slangReflection;
50    GFX_CHECK_CALL_ABORT(loadComputeProgram(
51        dstDevice,
52        shaderProgram,
53        "compute-trivial",
54        "computeMain",
55        slangReflection));
56
57    ComputePipelineDesc pipelineDesc = {};
58    pipelineDesc.program = shaderProgram.get();
59    ComPtr<IComputePipeline> pipelineState;
60    GFX_CHECK_CALL_ABORT(dstDevice->createComputePipeline(pipelineDesc, pipelineState.writeRef()));
61
62    auto queue = dstDevice->getQueue(QueueType::Graphics);
63    auto commandEncoder = queue->createCommandEncoder();
64    auto computePassEncoder = commandEncoder->beginComputePass();
65
66    auto rootObject = computePassEncoder->bindPipeline(pipelineState);
67
68    ShaderCursor rootCursor(rootObject);
69    // Bind buffer to the entry point.
70    rootCursor.getPath("buffer").setBinding(Binding(dstBuffer));
71
72    computePassEncoder->dispatchCompute(1, 1, 1);
73    computePassEncoder->end();
74    auto commandBuffer = commandEncoder->finish();
75    queue->submit(commandBuffer);
76    queue->waitOnHost();
77
78    compareComputeResult(dstDevice, dstBuffer, std::array{1.0f, 2.0f, 3.0f, 4.0f});
79}
80
81void sharedBufferTestAPI(UnitTestContext* context, DeviceType srcApi, DeviceType dstApi)
82{
83    auto srcDevice = createTestingDevice(context, srcApi);
84    auto dstDevice = createTestingDevice(context, dstApi);
85    if (!srcDevice || !dstDevice)
86    {
87        SLANG_IGNORE_TEST;
88    }
89
90    sharedBufferTestImpl(srcDevice, dstDevice, context);
91}
92#if SLANG_WIN64
93SLANG_UNIT_TEST(sharedBufferD3D12ToCUDA)
94{
95    sharedBufferTestAPI(unitTestContext, DeviceType::D3D12, DeviceType::CUDA);
96}
97
98SLANG_UNIT_TEST(sharedBufferVulkanToCUDA)
99{
100    sharedBufferTestAPI(unitTestContext, DeviceType::Vulkan, DeviceType::CUDA);
101}
102#endif
103} // namespace gfx_test