diff options
| author | Yong He <yonghe@outlook.com> | 2021-06-30 14:59:18 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-30 14:59:18 -0700 |
| commit | a03d21a5f54cba913c3f52e2822a433de8f39fdd (patch) | |
| tree | 84d24d4355cc4b3e941da9eab57147cd9d297ee4 /tools | |
| parent | 5395ef82535c283109b1ea6b89b737c5a39bf147 (diff) | |
[gfx] Add inline ray tracing support. (#1899)
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/gfx/cuda/render-cuda.cpp | 38 | ||||
| -rw-r--r-- | tools/gfx/d3d11/render-d3d11.cpp | 20 | ||||
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 55 | ||||
| -rw-r--r-- | tools/gfx/debug-layer.cpp | 227 | ||||
| -rw-r--r-- | tools/gfx/debug-layer.h | 95 | ||||
| -rw-r--r-- | tools/gfx/immediate-renderer-base.cpp | 54 | ||||
| -rw-r--r-- | tools/gfx/open-gl/render-gl.cpp | 2 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.cpp | 32 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.h | 23 | ||||
| -rw-r--r-- | tools/gfx/simple-transient-resource-heap.h | 2 | ||||
| -rw-r--r-- | tools/gfx/transient-resource-heap-base.h | 4 | ||||
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 657 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-api.h | 9 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-util.cpp | 144 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-util.h | 19 | ||||
| -rw-r--r-- | tools/platform/gui.cpp | 6 | ||||
| -rw-r--r-- | tools/render-test/render-test-main.cpp | 18 |
17 files changed, 1110 insertions, 295 deletions
diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp index 5a7e7babf..ffd197e57 100644 --- a/tools/gfx/cuda/render-cuda.cpp +++ b/tools/gfx/cuda/render-cuda.cpp @@ -921,22 +921,6 @@ public: : public IComputeCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IComputeCommandEncoder) - { - *outObject = static_cast<IComputeCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - - public: CommandWriter* m_writer; CommandBufferImpl* m_commandBuffer; RefPtr<ShaderObjectBase> m_rootObject; @@ -982,22 +966,6 @@ public: : public IResourceCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IResourceCommandEncoder) - { - *outObject = static_cast<IResourceCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - - public: CommandWriter* m_writer; void init(CommandBufferImpl* cmdBuffer) @@ -1037,6 +1005,12 @@ public: *outEncoder = &m_resourceCommandEncoder; } + virtual SLANG_NO_THROW void SLANG_MCALL + encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override + { + *outEncoder = nullptr; + } + virtual SLANG_NO_THROW void SLANG_MCALL close() override {} }; diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp index f2fe9b744..d74888812 100644 --- a/tools/gfx/d3d11/render-d3d11.cpp +++ b/tools/gfx/d3d11/render-d3d11.cpp @@ -1536,7 +1536,7 @@ protected: bufferDesc.defaultState = ResourceState::ConstantBuffer; bufferDesc.allowedStates = ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); - bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; + bufferDesc.cpuAccessFlags |= AccessFlag::Write; SLANG_RETURN_ON_FAIL( device->createBufferResource(bufferDesc, nullptr, bufferResourcePtr.writeRef())); m_ordinaryDataBuffer = static_cast<BufferResourceImpl*>(bufferResourcePtr.get()); @@ -2506,10 +2506,10 @@ static int _calcResourceAccessFlags(int accessFlags) switch (accessFlags) { case 0: return 0; - case IResource::AccessFlag::Read: return D3D11_CPU_ACCESS_READ; - case IResource::AccessFlag::Write: return D3D11_CPU_ACCESS_WRITE; - case IResource::AccessFlag::Read | - IResource::AccessFlag::Write: return D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + case AccessFlag::Read: return D3D11_CPU_ACCESS_READ; + case AccessFlag::Write: return D3D11_CPU_ACCESS_WRITE; + case AccessFlag::Read | + AccessFlag::Write: return D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; default: assert(!"Invalid flags"); return 0; } } @@ -2663,11 +2663,11 @@ Result D3D11Device::createBufferResource(const IBufferResource::Desc& descIn, co bufferDesc.BindFlags = d3dBindFlags; // For read we'll need to do some staging bufferDesc.CPUAccessFlags = - _calcResourceAccessFlags(descIn.cpuAccessFlags & IResource::AccessFlag::Write); + _calcResourceAccessFlags(descIn.cpuAccessFlags & AccessFlag::Write); bufferDesc.Usage = D3D11_USAGE_DEFAULT; // If written by CPU, make it dynamic - if ((descIn.cpuAccessFlags & IResource::AccessFlag::Write) && + if ((descIn.cpuAccessFlags & AccessFlag::Write) && !descIn.allowedStates.contains(ResourceState::UnorderedAccess)) { bufferDesc.Usage = D3D11_USAGE_DYNAMIC; @@ -2698,7 +2698,7 @@ Result D3D11Device::createBufferResource(const IBufferResource::Desc& descIn, co } } - if (srcDesc.cpuAccessFlags & IResource::AccessFlag::Write) + if (srcDesc.cpuAccessFlags & AccessFlag::Write) { bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; } @@ -2711,8 +2711,8 @@ Result D3D11Device::createBufferResource(const IBufferResource::Desc& descIn, co SLANG_RETURN_ON_FAIL(m_device->CreateBuffer(&bufferDesc, initData ? &subResourceData : nullptr, buffer->m_buffer.writeRef())); buffer->m_d3dUsage = bufferDesc.Usage; - if ((srcDesc.cpuAccessFlags & IResource::AccessFlag::Read) || - ((srcDesc.cpuAccessFlags & IResource::AccessFlag::Write) && bufferDesc.Usage != D3D11_USAGE_DYNAMIC)) + if ((srcDesc.cpuAccessFlags & AccessFlag::Read) || + ((srcDesc.cpuAccessFlags & AccessFlag::Write) && bufferDesc.Usage != D3D11_USAGE_DYNAMIC)) { D3D11_BUFFER_DESC bufDesc = {}; bufDesc.BindFlags = 0; diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index 79cbe2f9a..b8c95ef3a 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -578,7 +578,7 @@ public: bufferDesc.allowedStates = ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); bufferDesc.sizeInBytes = desc.constantBufferSize; - bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; + bufferDesc.cpuAccessFlags |= AccessFlag::Write; SLANG_RETURN_ON_FAIL(device->createBufferResource( bufferDesc, nullptr, @@ -3098,21 +3098,6 @@ public: , public PipelineCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IRenderCommandEncoder) - { - *outObject = static_cast<IRenderCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - public: RefPtr<RenderPassLayoutImpl> m_renderPass; RefPtr<FramebufferImpl> m_framebuffer; @@ -3481,22 +3466,6 @@ public: , public PipelineCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IComputeCommandEncoder) - { - *outObject = static_cast<IComputeCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() { return 1; } - - public: virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override { PipelineCommandEncoder::endEncodingImpl(); @@ -3548,22 +3517,6 @@ public: class ResourceCommandEncoderImpl : public IResourceCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IResourceCommandEncoder) - { - *outObject = static_cast<IResourceCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() { return 1; } - - public: CommandBufferImpl* m_commandBuffer; void init(D3D12Device* renderer, CommandBufferImpl* commandBuffer) { @@ -3615,6 +3568,12 @@ public: *outEncoder = &m_resourceCommandEncoder; } + virtual SLANG_NO_THROW void SLANG_MCALL + encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override + { + *outEncoder = nullptr; + } + virtual SLANG_NO_THROW void SLANG_MCALL close() override { m_cmdList->Close(); } }; diff --git a/tools/gfx/debug-layer.cpp b/tools/gfx/debug-layer.cpp index 26aa36535..7ad0dd31c 100644 --- a/tools/gfx/debug-layer.cpp +++ b/tools/gfx/debug-layer.cpp @@ -126,9 +126,6 @@ SLANG_GFX_DEBUG_GET_INTERFACE_IMPL_PARENT(BufferResource, Resource) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL_PARENT(TextureResource, Resource) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(CommandBuffer) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(CommandQueue) -SLANG_GFX_DEBUG_GET_INTERFACE_IMPL_PARENT(ComputeCommandEncoder, CommandEncoder) -SLANG_GFX_DEBUG_GET_INTERFACE_IMPL_PARENT(RenderCommandEncoder, CommandEncoder) -SLANG_GFX_DEBUG_GET_INTERFACE_IMPL_PARENT(ResourceCommandEncoder, CommandEncoder) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(Framebuffer) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(FramebufferLayout) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(InputLayout) @@ -141,11 +138,48 @@ SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(ShaderProgram) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(Swapchain) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(TransientResourceHeap) SLANG_GFX_DEBUG_GET_INTERFACE_IMPL(QueryPool) +SLANG_GFX_DEBUG_GET_INTERFACE_IMPL_PARENT(AccelerationStructure, ResourceView) #undef SLANG_GFX_DEBUG_GET_INTERFACE_IMPL #undef SLANG_GFX_DEBUG_GET_INTERFACE_IMPL_PARENT +// Utility conversion functions to get Debug* object or the inner object from a user provided +// pointer. +#define SLANG_GFX_DEBUG_GET_OBJ_IMPL(type) \ + static Debug##type* getDebugObj(I##type* ptr) { return static_cast<Debug##type*>(ptr); } \ + static I##type* getInnerObj(I##type* ptr) \ + { \ + if (!ptr) return nullptr; \ + auto debugObj = getDebugObj(ptr); \ + return debugObj->baseObject; \ + } + +SLANG_GFX_DEBUG_GET_OBJ_IMPL(Device) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(BufferResource) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(TextureResource) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(CommandBuffer) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(CommandQueue) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(ComputeCommandEncoder) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(RenderCommandEncoder) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(ResourceCommandEncoder) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(RayTracingCommandEncoder) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(Framebuffer) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(FramebufferLayout) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(InputLayout) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(RenderPassLayout) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(PipelineState) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(ResourceView) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(SamplerState) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(ShaderObject) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(ShaderProgram) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(Swapchain) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(TransientResourceHeap) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(QueryPool) +SLANG_GFX_DEBUG_GET_OBJ_IMPL(AccelerationStructure) + +#undef SLANG_GFX_DEBUG_GET_OBJ_IMPL + Result DebugDevice::getFeatures(const char** outFeatures, UInt bufferSize, UInt* outFeatureCount) { SLANG_GFX_API_FUNC; @@ -267,6 +301,30 @@ Result DebugDevice::createBufferView( return result; } +Result DebugDevice::getAccelerationStructurePrebuildInfo( + const IAccelerationStructure::BuildInputs& buildInputs, + IAccelerationStructure::PrebuildInfo* outPrebuildInfo) +{ + SLANG_GFX_API_FUNC; + + return baseObject->getAccelerationStructurePrebuildInfo(buildInputs, outPrebuildInfo); +} + +Result DebugDevice::createAccelerationStructure( + const IAccelerationStructure::CreateDesc& desc, + IAccelerationStructure** outAS) +{ + SLANG_GFX_API_FUNC; + auto innerDesc = desc; + innerDesc.buffer = getInnerObj(innerDesc.buffer); + RefPtr<DebugAccelerationStructure> outObject = new DebugAccelerationStructure(); + auto result = baseObject->createAccelerationStructure(innerDesc, outObject->baseObject.writeRef()); + if (SLANG_FAILED(result)) + return result; + returnComPtr(outAS, outObject); + return SLANG_OK; +} + Result DebugDevice::createFramebufferLayout( IFramebufferLayout::Desc const& desc, IFramebufferLayout** outFrameBuffer) @@ -540,7 +598,7 @@ void DebugCommandBuffer::encodeRenderCommands( framebuffer ? static_cast<DebugFramebuffer*>(framebuffer)->baseObject : nullptr; m_renderCommandEncoder.isOpen = true; baseObject->encodeRenderCommands( - innerRenderPass, innerFramebuffer, m_renderCommandEncoder.baseObject.writeRef()); + innerRenderPass, innerFramebuffer, &m_renderCommandEncoder.baseObject); if (m_renderCommandEncoder.baseObject) *outEncoder = &m_renderCommandEncoder; else @@ -553,8 +611,15 @@ void DebugCommandBuffer::encodeComputeCommands(IComputeCommandEncoder** outEncod checkCommandBufferOpenWhenCreatingEncoder(); checkEncodersClosedBeforeNewEncoder(); m_computeCommandEncoder.isOpen = true; - baseObject->encodeComputeCommands(m_computeCommandEncoder.baseObject.writeRef()); - *outEncoder = &m_computeCommandEncoder; + baseObject->encodeComputeCommands(&m_computeCommandEncoder.baseObject); + if (m_computeCommandEncoder.baseObject) + { + *outEncoder = &m_computeCommandEncoder; + } + else + { + *outEncoder = nullptr; + } } void DebugCommandBuffer::encodeResourceCommands(IResourceCommandEncoder** outEncoder) @@ -563,8 +628,32 @@ void DebugCommandBuffer::encodeResourceCommands(IResourceCommandEncoder** outEnc checkCommandBufferOpenWhenCreatingEncoder(); checkEncodersClosedBeforeNewEncoder(); m_resourceCommandEncoder.isOpen = true; - baseObject->encodeResourceCommands(m_resourceCommandEncoder.baseObject.writeRef()); - *outEncoder = &m_resourceCommandEncoder; + baseObject->encodeResourceCommands(&m_resourceCommandEncoder.baseObject); + if (m_resourceCommandEncoder.baseObject) + { + *outEncoder = &m_resourceCommandEncoder; + } + else + { + *outEncoder = nullptr; + } +} + +void DebugCommandBuffer::encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) +{ + SLANG_GFX_API_FUNC; + checkCommandBufferOpenWhenCreatingEncoder(); + checkEncodersClosedBeforeNewEncoder(); + m_rayTracingCommandEncoder.isOpen = true; + baseObject->encodeRayTracingCommands(&m_rayTracingCommandEncoder.baseObject); + if (m_rayTracingCommandEncoder.baseObject) + { + *outEncoder = &m_rayTracingCommandEncoder; + } + else + { + *outEncoder = nullptr; + } } void DebugCommandBuffer::close() @@ -619,6 +708,7 @@ void DebugCommandBuffer::checkCommandBufferOpenWhenCreatingEncoder() void DebugComputeCommandEncoder::endEncoding() { SLANG_GFX_API_FUNC; + isOpen = false; baseObject->endEncoding(); } @@ -650,6 +740,7 @@ void DebugComputeCommandEncoder::writeTimestamp(IQueryPool* pool, SlangInt index void DebugRenderCommandEncoder::endEncoding() { SLANG_GFX_API_FUNC; + isOpen = false; baseObject->endEncoding(); } @@ -738,6 +829,7 @@ void DebugRenderCommandEncoder::writeTimestamp(IQueryPool* pool, SlangInt index) void DebugResourceCommandEncoder::endEncoding() { SLANG_GFX_API_FUNC; + isOpen = false; baseObject->endEncoding(); } @@ -771,6 +863,103 @@ void DebugResourceCommandEncoder::uploadBufferData( baseObject->uploadBufferData(dstImpl->baseObject, offset, size, data); } +void DebugRayTracingCommandEncoder::endEncoding() +{ + SLANG_GFX_API_FUNC; + isOpen = false; + baseObject->endEncoding(); +} + +SLANG_NO_THROW void SLANG_MCALL + DebugRayTracingCommandEncoder::writeTimestamp(IQueryPool* pool, SlangInt index) +{ + SLANG_GFX_API_FUNC; + baseObject->writeTimestamp(static_cast<DebugQueryPool*>(pool)->baseObject, index); +} + +void DebugRayTracingCommandEncoder::buildAccelerationStructure( + const IAccelerationStructure::BuildDesc& desc, + int propertyQueryCount, + AccelerationStructureQueryDesc* queryDescs) +{ + SLANG_GFX_API_FUNC; + IAccelerationStructure::BuildDesc innerDesc = desc; + innerDesc.dest = getInnerObj(innerDesc.dest); + innerDesc.source = getInnerObj(innerDesc.source); + List<AccelerationStructureQueryDesc> innerQueryDescs; + innerQueryDescs.addRange(queryDescs, propertyQueryCount); + for (auto& innerQueryDesc : innerQueryDescs) + { + innerQueryDesc.queryPool = getInnerObj(innerQueryDesc.queryPool); + } + baseObject->buildAccelerationStructure( + innerDesc, propertyQueryCount, innerQueryDescs.getBuffer()); +} + +void DebugRayTracingCommandEncoder::copyAccelerationStructure( + IAccelerationStructure* dest, + IAccelerationStructure* src, + AccelerationStructureCopyMode mode) +{ + SLANG_GFX_API_FUNC; + auto innerDest = getInnerObj(dest); + auto innerSrc = getInnerObj(src); + baseObject->copyAccelerationStructure(innerDest, innerSrc, mode); +} + +void DebugRayTracingCommandEncoder::queryAccelerationStructureProperties( + int accelerationStructureCount, + IAccelerationStructure* const* accelerationStructures, + int queryCount, + AccelerationStructureQueryDesc* queryDescs) +{ + SLANG_GFX_API_FUNC; + List<IAccelerationStructure*> innerAS; + for (int i = 0; i < accelerationStructureCount; i++) + { + innerAS.add(getInnerObj(accelerationStructures[i])); + } + List<AccelerationStructureQueryDesc> innerQueryDescs; + innerQueryDescs.addRange(queryDescs, queryCount); + for (auto& innerQueryDesc : innerQueryDescs) + { + innerQueryDesc.queryPool = getInnerObj(innerQueryDesc.queryPool); + } + baseObject->queryAccelerationStructureProperties( + accelerationStructureCount, innerAS.getBuffer(), queryCount, innerQueryDescs.getBuffer()); +} + +void DebugRayTracingCommandEncoder::serializeAccelerationStructure( + DeviceAddress dest, + IAccelerationStructure* source) +{ + SLANG_GFX_API_FUNC; + baseObject->serializeAccelerationStructure(dest, getInnerObj(source)); +} + +void DebugRayTracingCommandEncoder::deserializeAccelerationStructure( + IAccelerationStructure* dest, + DeviceAddress source) +{ + SLANG_GFX_API_FUNC; + baseObject->deserializeAccelerationStructure(getInnerObj(dest), source); +} + +void DebugRayTracingCommandEncoder::memoryBarrier( + int count, + IAccelerationStructure* const* structures, + AccessFlag::Enum sourceAccess, + AccessFlag::Enum destAccess) +{ + SLANG_GFX_API_FUNC; + List<IAccelerationStructure*> innerAS; + for (int i = 0; i < count; i++) + { + innerAS.add(getInnerObj(structures[i])); + } + baseObject->memoryBarrier(count, innerAS.getBuffer(), sourceAccess, destAccess); +} + const ICommandQueue::Desc& DebugCommandQueue::getDesc() { SLANG_GFX_API_FUNC; @@ -794,6 +983,14 @@ void DebugCommandQueue::executeCommandBuffers(uint32_t count, ICommandBuffer* co "before submitting to a command queue.", cmdBufferImpl->uid); } + if (i > 0) + { + if (cmdBufferImpl->m_transientHeap != getDebugObj(commandBuffers[0])->m_transientHeap) + { + GFX_DIAGNOSE_ERROR("Command buffers passed to a single executeCommandBuffers " + "call must be allocated from the same transient heap."); + } + } } baseObject->executeCommandBuffers(count, innerCommandBuffers.getBuffer()); } @@ -810,6 +1007,7 @@ Result DebugTransientResourceHeap::createCommandBuffer(ICommandBuffer** outComma { SLANG_GFX_API_FUNC; RefPtr<DebugCommandBuffer> outObject = new DebugCommandBuffer(); + outObject->m_transientHeap = this; auto result = baseObject->createCommandBuffer(outObject->baseObject.writeRef()); if (SLANG_FAILED(result)) return result; @@ -1009,14 +1207,25 @@ Result DebugRootShaderObject::setSpecializationArgs( const slang::SpecializationArg* args, uint32_t count) { + SLANG_GFX_API_FUNC; + return baseObject->setSpecializationArgs(offset, args, count); } Result DebugQueryPool::getResult(SlangInt index, SlangInt count, uint64_t* data) { - if (index < 0 || index + count >= desc.count) + SLANG_GFX_API_FUNC; + + if (index < 0 || index + count > desc.count) GFX_DIAGNOSE_ERROR("index is out of bounds."); return baseObject->getResult(index, count, data); } +DeviceAddress DebugAccelerationStructure::getDeviceAddress() +{ + SLANG_GFX_API_FUNC; + + return baseObject->getDeviceAddress(); +} + } // namespace gfx diff --git a/tools/gfx/debug-layer.h b/tools/gfx/debug-layer.h index 6225260dd..8ab1146d0 100644 --- a/tools/gfx/debug-layer.h +++ b/tools/gfx/debug-layer.h @@ -23,6 +23,15 @@ public: Slang::ComPtr<TInterface> baseObject; }; +template <typename TInterface> +class UnownedDebugObject + : public TInterface + , public DebugObjectBase +{ +public: + TInterface* baseObject = nullptr; +}; + class DebugDevice : public DebugObject<IDevice> { public: @@ -57,6 +66,12 @@ public: IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) override; + virtual SLANG_NO_THROW Result SLANG_MCALL getAccelerationStructurePrebuildInfo( + const IAccelerationStructure::BuildInputs& buildInputs, + IAccelerationStructure::PrebuildInfo* outPrebuildInfo) override; + virtual SLANG_NO_THROW Result SLANG_MCALL createAccelerationStructure( + const IAccelerationStructure::CreateDesc& desc, + IAccelerationStructure** outView) override; virtual SLANG_NO_THROW Result SLANG_MCALL createFramebufferLayout( IFramebufferLayout::Desc const& desc, IFramebufferLayout** outFrameBuffer) override; @@ -147,6 +162,16 @@ public: IResourceView* getInterface(const Slang::Guid& guid); }; +class DebugAccelerationStructure : public DebugObject<IAccelerationStructure> +{ +public: + SLANG_COM_OBJECT_IUNKNOWN_ALL; + +public: + IAccelerationStructure* getInterface(const Slang::Guid& guid); + virtual SLANG_NO_THROW DeviceAddress SLANG_MCALL getDeviceAddress() override; +}; + class DebugSamplerState : public DebugObject<ISamplerState> { public: @@ -228,16 +253,9 @@ public: class DebugCommandBuffer; -class DebugComputeCommandEncoder : public DebugObject<IComputeCommandEncoder> +class DebugComputeCommandEncoder : public UnownedDebugObject<IComputeCommandEncoder> { public: - SLANG_COM_OBJECT_IUNKNOWN_QUERY_INTERFACE; - -public: - IComputeCommandEncoder* getInterface(const Slang::Guid& guid); - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override; virtual SLANG_NO_THROW Result SLANG_MCALL bindPipeline(IPipelineState* state, IShaderObject** outRootShaderObject) override; @@ -249,16 +267,9 @@ public: bool isOpen = false; }; -class DebugRenderCommandEncoder : public DebugObject<IRenderCommandEncoder> +class DebugRenderCommandEncoder : public UnownedDebugObject<IRenderCommandEncoder> { public: - SLANG_COM_OBJECT_IUNKNOWN_QUERY_INTERFACE; - -public: - IRenderCommandEncoder* getInterface(const Slang::Guid& guid); - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override; virtual SLANG_NO_THROW Result SLANG_MCALL bindPipeline(IPipelineState* state, IShaderObject** outRootShaderObject) override; @@ -287,16 +298,9 @@ public: bool isOpen = false; }; -class DebugResourceCommandEncoder : public DebugObject<IResourceCommandEncoder> +class DebugResourceCommandEncoder : public UnownedDebugObject<IResourceCommandEncoder> { public: - SLANG_COM_OBJECT_IUNKNOWN_QUERY_INTERFACE; - -public: - IResourceCommandEncoder* getInterface(const Slang::Guid& guid); - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override; virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer( IBufferResource* dst, @@ -313,15 +317,56 @@ public: bool isOpen = false; }; +class DebugRayTracingCommandEncoder : public UnownedDebugObject<IRayTracingCommandEncoder> +{ +public: + virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override; + virtual SLANG_NO_THROW void SLANG_MCALL + writeTimestamp(IQueryPool* pool, SlangInt index) override; + virtual SLANG_NO_THROW void SLANG_MCALL buildAccelerationStructure( + const IAccelerationStructure::BuildDesc& desc, + int propertyQueryCount, + AccelerationStructureQueryDesc* queryDescs) override; + virtual SLANG_NO_THROW void SLANG_MCALL copyAccelerationStructure( + IAccelerationStructure* dest, + IAccelerationStructure* src, + AccelerationStructureCopyMode mode) override; + virtual SLANG_NO_THROW void SLANG_MCALL queryAccelerationStructureProperties( + int accelerationStructureCount, + IAccelerationStructure* const* accelerationStructures, + int queryCount, + AccelerationStructureQueryDesc* queryDescs) override; + virtual SLANG_NO_THROW void SLANG_MCALL + serializeAccelerationStructure(DeviceAddress dest, IAccelerationStructure* source) override; + virtual SLANG_NO_THROW void SLANG_MCALL deserializeAccelerationStructure( + IAccelerationStructure* dest, + DeviceAddress source) override; + virtual SLANG_NO_THROW void memoryBarrier( + int count, + IAccelerationStructure* const* structures, + AccessFlag::Enum sourceAccess, + AccessFlag::Enum destAccess) override; + +public: + DebugCommandBuffer* commandBuffer; + bool isOpen = false; +}; + +class DebugTransientResourceHeap; + class DebugCommandBuffer : public DebugObject<ICommandBuffer> { public: SLANG_COM_OBJECT_IUNKNOWN_ALL; +public: + DebugTransientResourceHeap* m_transientHeap; + private: DebugRenderCommandEncoder m_renderCommandEncoder; DebugComputeCommandEncoder m_computeCommandEncoder; DebugResourceCommandEncoder m_resourceCommandEncoder; + DebugRayTracingCommandEncoder m_rayTracingCommandEncoder; public: DebugCommandBuffer(); @@ -334,6 +379,8 @@ public: encodeComputeCommands(IComputeCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW void SLANG_MCALL encodeResourceCommands(IResourceCommandEncoder** outEncoder) override; + virtual SLANG_NO_THROW void SLANG_MCALL + encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW void SLANG_MCALL close() override; private: diff --git a/tools/gfx/immediate-renderer-base.cpp b/tools/gfx/immediate-renderer-base.cpp index 8fffbfdfa..eae6c82b0 100644 --- a/tools/gfx/immediate-renderer-base.cpp +++ b/tools/gfx/immediate-renderer-base.cpp @@ -50,22 +50,6 @@ public: : public IRenderCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IRenderCommandEncoder) - { - *outObject = static_cast<IRenderCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - - public: CommandWriter* m_writer; CommandBufferImpl* m_commandBuffer; virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override {} @@ -188,22 +172,6 @@ public: : public IComputeCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IComputeCommandEncoder) - { - *outObject = static_cast<IComputeCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - - public: CommandWriter* m_writer; CommandBufferImpl* m_commandBuffer; @@ -252,22 +220,6 @@ public: : public IResourceCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IResourceCommandEncoder) - { - *outObject = static_cast<IResourceCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - - public: CommandWriter* m_writer; void init(CommandBufferImpl* cmdBuffer) @@ -307,6 +259,12 @@ public: *outEncoder = &m_resourceCommandEncoder; } + virtual SLANG_NO_THROW void SLANG_MCALL + encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override + { + *outEncoder = nullptr; + } + virtual SLANG_NO_THROW void SLANG_MCALL close() override { } void execute() diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp index 81a1a6ccd..92f8680d7 100644 --- a/tools/gfx/open-gl/render-gl.cpp +++ b/tools/gfx/open-gl/render-gl.cpp @@ -1257,7 +1257,7 @@ public: bufferDesc.defaultState = ResourceState::ConstantBuffer; bufferDesc.allowedStates = ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); - bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; + bufferDesc.cpuAccessFlags |= AccessFlag::Write; SLANG_RETURN_ON_FAIL( device->createBufferResource(bufferDesc, nullptr, bufferResourcePtr.writeRef())); m_ordinaryDataBuffer = static_cast<BufferResourceImpl*>(bufferResourcePtr.get()); diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp index 9d6c85309..c88081547 100644 --- a/tools/gfx/renderer-shared.cpp +++ b/tools/gfx/renderer-shared.cpp @@ -25,13 +25,11 @@ const Slang::Guid GfxGUID::IID_IDevice = SLANG_UUID_IDevice; const Slang::Guid GfxGUID::IID_IShaderObject = SLANG_UUID_IShaderObject; const Slang::Guid GfxGUID::IID_IRenderPassLayout = SLANG_UUID_IRenderPassLayout; -const Slang::Guid GfxGUID::IID_ICommandEncoder = SLANG_UUID_ICommandEncoder; -const Slang::Guid GfxGUID::IID_IRenderCommandEncoder = SLANG_UUID_IRenderCommandEncoder; -const Slang::Guid GfxGUID::IID_IComputeCommandEncoder = SLANG_UUID_IComputeCommandEncoder; -const Slang::Guid GfxGUID::IID_IResourceCommandEncoder = SLANG_UUID_IResourceCommandEncoder; +const Slang::Guid GfxGUID::IID_IRayTracingCommandEncoder = SLANG_UUID_IRayTracingCommandEncoder; const Slang::Guid GfxGUID::IID_ICommandBuffer = SLANG_UUID_ICommandBuffer; const Slang::Guid GfxGUID::IID_ICommandQueue = SLANG_UUID_ICommandQueue; const Slang::Guid GfxGUID::IID_IQueryPool = SLANG_UUID_IQueryPool; +const Slang::Guid GfxGUID::IID_IAccelerationStructure = SLANG_UUID_IAccelerationStructure; StageType translateStage(SlangStage slangStage) @@ -119,6 +117,14 @@ IResourceView* ResourceViewBase::getInterface(const Guid& guid) return nullptr; } +IAccelerationStructure* AccelerationStructureBase::getInterface(const Slang::Guid& guid) +{ + if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IResourceView || + guid == GfxGUID::IID_IAccelerationStructure) + return static_cast<IAccelerationStructure*>(this); + return nullptr; +} + IShaderObject* ShaderObjectBase::getInterface(const Guid& guid) { if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IShaderObject) @@ -279,6 +285,24 @@ SLANG_NO_THROW Result SLANG_MCALL RendererBase::createShaderObject( return createShaderObject(shaderObjectLayout, outObject); } +Result RendererBase::getAccelerationStructurePrebuildInfo( + const IAccelerationStructure::BuildInputs& buildInputs, + IAccelerationStructure::PrebuildInfo* outPrebuildInfo) +{ + SLANG_UNUSED(buildInputs); + SLANG_UNUSED(outPrebuildInfo); + return SLANG_E_NOT_AVAILABLE; +} + +Result RendererBase::createAccelerationStructure( + const IAccelerationStructure::CreateDesc& desc, + IAccelerationStructure** outView) +{ + SLANG_UNUSED(desc); + SLANG_UNUSED(outView); + return SLANG_E_NOT_AVAILABLE; +} + Result RendererBase::getShaderObjectLayout( slang::TypeReflection* type, ShaderObjectContainerType container, diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h index 127987726..e3580b9b6 100644 --- a/tools/gfx/renderer-shared.h +++ b/tools/gfx/renderer-shared.h @@ -33,9 +33,11 @@ struct GfxGUID static const Slang::Guid IID_IRenderCommandEncoder; static const Slang::Guid IID_IComputeCommandEncoder; static const Slang::Guid IID_IResourceCommandEncoder; + static const Slang::Guid IID_IRayTracingCommandEncoder; static const Slang::Guid IID_ICommandBuffer; static const Slang::Guid IID_ICommandQueue; static const Slang::Guid IID_IQueryPool; + static const Slang::Guid IID_IAccelerationStructure; }; // We use a `BreakableReference` to avoid the cyclic reference situation in gfx implementation. @@ -252,6 +254,15 @@ public: IResourceView* getInterface(const Slang::Guid& guid); }; +class AccelerationStructureBase + : public IAccelerationStructure + , public Slang::ComObject +{ +public: + SLANG_COM_OBJECT_IUNKNOWN_ALL + IAccelerationStructure* getInterface(const Slang::Guid& guid); +}; + class RendererBase; typedef uint32_t ShaderComponentID; @@ -1061,6 +1072,18 @@ public: ShaderObjectContainerType containerType, IShaderObject** outObject) SLANG_OVERRIDE; + // Provides a default implementation that returns SLANG_E_NOT_AVAILABLE for platforms + // without ray tracing support. + virtual SLANG_NO_THROW Result SLANG_MCALL getAccelerationStructurePrebuildInfo( + const IAccelerationStructure::BuildInputs& buildInputs, + IAccelerationStructure::PrebuildInfo* outPrebuildInfo) override; + + // Provides a default implementation that returns SLANG_E_NOT_AVAILABLE for platforms + // without ray tracing support. + virtual SLANG_NO_THROW Result SLANG_MCALL createAccelerationStructure( + const IAccelerationStructure::CreateDesc& desc, + IAccelerationStructure** outView) override; + Result getShaderObjectLayout( slang::TypeReflection* type, ShaderObjectContainerType container, diff --git a/tools/gfx/simple-transient-resource-heap.h b/tools/gfx/simple-transient-resource-heap.h index d8ab3517d..4340d49df 100644 --- a/tools/gfx/simple-transient-resource-heap.h +++ b/tools/gfx/simple-transient-resource-heap.h @@ -35,7 +35,7 @@ public: bufferDesc.allowedStates = ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); bufferDesc.defaultState = ResourceState::ConstantBuffer; bufferDesc.sizeInBytes = desc.constantBufferSize; - bufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; + bufferDesc.cpuAccessFlags = AccessFlag::Write; SLANG_RETURN_ON_FAIL( device->createBufferResource(bufferDesc, nullptr, m_constantBuffer.writeRef())); return SLANG_OK; diff --git a/tools/gfx/transient-resource-heap-base.h b/tools/gfx/transient-resource-heap-base.h index ef8a61616..f11a91c14 100644 --- a/tools/gfx/transient-resource-heap-base.h +++ b/tools/gfx/transient-resource-heap-base.h @@ -45,7 +45,7 @@ public: bufferDesc.allowedStates = ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); bufferDesc.sizeInBytes = desc.constantBufferSize; - bufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; + bufferDesc.cpuAccessFlags = AccessFlag::Write; SLANG_RETURN_ON_FAIL( m_device->createBufferResource(bufferDesc, nullptr, bufferPtr.writeRef())); m_constantBuffers.add(static_cast<TBufferResource*>(bufferPtr.get())); @@ -90,7 +90,7 @@ public: bufferDesc.defaultState = ResourceState::ConstantBuffer; bufferDesc.allowedStates = ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); - bufferDesc.cpuAccessFlags |= IResource::AccessFlag::Write; + bufferDesc.cpuAccessFlags |= AccessFlag::Write; size_t lastConstantBufferSize = 0; if (m_constantBuffers.getCount()) { diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 97a527ca6..10cc7aae5 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -120,6 +120,15 @@ public: size_t offset, size_t size, ISlangBlob** outBlob) override; + + virtual SLANG_NO_THROW Result SLANG_MCALL getAccelerationStructurePrebuildInfo( + const IAccelerationStructure::BuildInputs& buildInputs, + IAccelerationStructure::PrebuildInfo* outPrebuildInfo) override; + + virtual SLANG_NO_THROW Result SLANG_MCALL createAccelerationStructure( + const IAccelerationStructure::CreateDesc& desc, + IAccelerationStructure** outView) override; + void waitForGpu(); virtual SLANG_NO_THROW const DeviceInfo& SLANG_MCALL getDeviceInfo() const override { @@ -128,6 +137,40 @@ public: /// Dtor ~VKDevice(); +public: + // Float16 features + VkPhysicalDeviceFloat16Int8FeaturesKHR float16Features = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR}; + // 16 bit storage features + VkPhysicalDevice16BitStorageFeatures storage16BitFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_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}; + // Timeline Semaphore features + VkPhysicalDeviceTimelineSemaphoreFeatures timelineFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES}; + // Extended dynamic state features + VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT}; + // Subgroup extended type features + VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures shaderSubgroupExtendedTypeFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES}; + // Acceleration structure features + VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; + // Ray query (inline ray-tracing) features + VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR}; + // Buffer device address features + VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES}; + +public: + class Buffer { public: @@ -303,6 +346,28 @@ public: VkDeviceSize size; }; + class AccelerationStructureImpl : public AccelerationStructureBase + { + public: + VkAccelerationStructureKHR m_vkHandle = VK_NULL_HANDLE; + RefPtr<BufferResourceImpl> m_buffer; + VkDeviceSize m_offset; + VkDeviceSize m_size; + RefPtr<VKDevice> m_device; + public: + virtual SLANG_NO_THROW DeviceAddress SLANG_MCALL getDeviceAddress() override + { + return m_buffer->getDeviceAddress() + m_offset; + } + ~AccelerationStructureImpl() + { + if (m_device) + { + m_device->m_api.vkDestroyAccelerationStructureKHR(m_device->m_api.m_device, m_vkHandle, nullptr); + } + } + }; + class FramebufferLayoutImpl : public FramebufferLayoutBase { public: @@ -2101,7 +2166,6 @@ public: class PipelineCommandEncoder : public RefObject { public: - bool m_isOpen = false; CommandBufferImpl* m_commandBuffer; VkCommandBuffer m_vkCommandBuffer; VkCommandBuffer m_vkPreCommandBuffer = VK_NULL_HANDLE; @@ -2130,7 +2194,6 @@ public: void endEncodingImpl() { - m_isOpen = false; for (auto& pipeline : m_boundPipelines) pipeline = VK_NULL_HANDLE; } @@ -2668,6 +2731,36 @@ public: } } + static void writeAccelerationStructureDescriptor( + RootBindingContext& context, + BindingOffset const& offset, + VkDescriptorType descriptorType, + ArrayView<RefPtr<ResourceViewImpl>> resourceViews) + { + auto descriptorSet = context.descriptorSets[offset.bindingSet]; + + Index count = resourceViews.getCount(); + for (Index i = 0; i < count; ++i) + { + auto accelerationStructure = static_cast<AccelerationStructureImpl*>( + static_cast<IResourceView*>(resourceViews[i].Ptr())); + + VkWriteDescriptorSetAccelerationStructureKHR writeAS = {}; + writeAS.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR; + writeAS.accelerationStructureCount = 1; + writeAS.pAccelerationStructures = &accelerationStructure->m_vkHandle; + VkWriteDescriptorSet write = {}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.descriptorCount = 1; + write.descriptorType = descriptorType; + write.dstArrayElement = uint32_t(i); + write.dstBinding = offset.binding; + write.dstSet = descriptorSet; + write.pNext = &writeAS; + writeDescriptor(context, write); + } + } + static void writeTextureDescriptor( RootBindingContext& context, BindingOffset const& offset, @@ -2881,7 +2974,15 @@ public: VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, m_resourceViews.getArrayView(baseIndex, count)); break; - + case slang::BindingType::RayTracingAccelerationStructure: + rangeOffset.bindingSet += bindingRangeInfo.setOffset; + rangeOffset.binding += bindingRangeInfo.bindingOffset; + writeAccelerationStructureDescriptor( + context, + rangeOffset, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, + m_resourceViews.getArrayView(baseIndex, count)); + break; case slang::BindingType::VaryingInput: case slang::BindingType::VaryingOutput: break; @@ -3473,7 +3574,6 @@ public: VkCommandBuffer m_commandBuffer; VkCommandBuffer m_preCommandBuffer = VK_NULL_HANDLE; VkCommandPool m_pool; - VkFence m_fence; VKDevice* m_renderer; BreakableReference<TransientResourceHeapImpl> m_transientHeap; bool m_isPreCommandBufferEmpty = true; @@ -3485,13 +3585,11 @@ public: Result init( VKDevice* renderer, VkCommandPool pool, - VkFence fence, TransientResourceHeapImpl* transientHeap) { m_renderer = renderer; m_transientHeap = transientHeap; m_pool = pool; - m_fence = fence; auto& api = renderer->m_api; VkCommandBufferAllocateInfo allocInfo = {}; @@ -3576,21 +3674,6 @@ public: VkIndexType m_boundIndexFormat; public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IRenderCommandEncoder) - { - *outObject = static_cast<IRenderCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - void beginPass(IRenderPassLayout* renderPass, IFramebuffer* framebuffer) { FramebufferImpl* framebufferImpl = static_cast<FramebufferImpl*>(framebuffer); @@ -3610,7 +3693,6 @@ public: beginInfo.pClearValues = framebufferImpl->m_clearValues; auto& api = *m_api; api.vkCmdBeginRenderPass(m_vkCommandBuffer, &beginInfo, VK_SUBPASS_CONTENTS_INLINE); - m_isOpen = true; } virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override @@ -3825,7 +3907,6 @@ public: m_renderCommandEncoder = new RenderCommandEncoder(); m_renderCommandEncoder->init(this); } - assert(!m_renderCommandEncoder->m_isOpen); m_renderCommandEncoder->beginPass(renderPass, framebuffer); *outEncoder = m_renderCommandEncoder.Ptr(); } @@ -3835,21 +3916,6 @@ public: , public PipelineCommandEncoder { public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IComputeCommandEncoder) - { - *outObject = static_cast<IComputeCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - public: virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override { endEncodingImpl(); @@ -3893,7 +3959,6 @@ public: m_computeCommandEncoder = new ComputeCommandEncoder(); m_computeCommandEncoder->init(this); } - assert(!m_computeCommandEncoder->m_isOpen); *outEncoder = m_computeCommandEncoder.Ptr(); } @@ -3904,21 +3969,6 @@ public: public: CommandBufferImpl* m_commandBuffer; public: - virtual SLANG_NO_THROW SlangResult SLANG_MCALL - queryInterface(SlangUUID const& uuid, void** outObject) override - { - if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || - uuid == GfxGUID::IID_IResourceCommandEncoder) - { - *outObject = static_cast<IResourceCommandEncoder*>(this); - return SLANG_OK; - } - *outObject = nullptr; - return SLANG_E_NO_INTERFACE; - } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; } - virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; } - public: virtual SLANG_NO_THROW void SLANG_MCALL copyBuffer( IBufferResource* dst, size_t dstOffset, @@ -4006,6 +4056,264 @@ public: *outEncoder = m_resourceCommandEncoder.Ptr(); } + class RayTracingCommandEncoder + : public IRayTracingCommandEncoder + , public RefObject + { + public: + CommandBufferImpl* m_commandBuffer; + + public: + void init(CommandBufferImpl* commandBuffer) { m_commandBuffer = commandBuffer; } + + inline VkAccessFlags translateAccelerationStructureAccessFlag(AccessFlag::Enum access) + { + VkAccessFlags result = 0; + if (access & AccessFlag::Read) + result |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT; + if (access & AccessFlag::Write) + result |= VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR; + return result; + } + + inline void _memoryBarrier( + int count, + IAccelerationStructure* const* structures, + AccessFlag::Enum srcAccess, + AccessFlag::Enum destAccess) + { + ShortList<VkBufferMemoryBarrier> memBarriers; + memBarriers.setCount(count); + for (int i = 0; i < count; i++) + { + memBarriers[i].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + memBarriers[i].pNext = nullptr; + memBarriers[i].dstAccessMask = + translateAccelerationStructureAccessFlag(destAccess); + memBarriers[i].srcAccessMask = + translateAccelerationStructureAccessFlag(srcAccess); + memBarriers[i].srcQueueFamilyIndex = + m_commandBuffer->m_renderer->m_queueFamilyIndex; + memBarriers[i].dstQueueFamilyIndex = + m_commandBuffer->m_renderer->m_queueFamilyIndex; + + auto asImpl = static_cast<AccelerationStructureImpl*>(structures[i]); + memBarriers[i].buffer = asImpl->m_buffer->m_buffer.m_buffer; + memBarriers[i].offset = asImpl->m_offset; + memBarriers[i].size = asImpl->m_size; + } + m_commandBuffer->m_renderer->m_api.vkCmdPipelineBarrier( + m_commandBuffer->m_commandBuffer, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, + 0, + nullptr, + (uint32_t)memBarriers.getCount(), + memBarriers.getArrayView().getBuffer(), + 0, + nullptr); + } + + inline void _queryAccelerationStructureProperties( + int accelerationStructureCount, + IAccelerationStructure* const* accelerationStructures, + int queryCount, + AccelerationStructureQueryDesc* queryDescs) + { + ShortList<VkAccelerationStructureKHR> vkHandles; + vkHandles.setCount(accelerationStructureCount); + for (int i = 0; i < accelerationStructureCount; i++) + { + vkHandles[i] = + static_cast<AccelerationStructureImpl*>(accelerationStructures[i]) + ->m_vkHandle; + } + auto vkHandlesView = vkHandles.getArrayView(); + for (int i = 0; i < queryCount; i++) + { + VkQueryType queryType; + switch (queryDescs[i].queryType) + { + case QueryType::AccelerationStructureCompactedSize: + queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR; + break; + case QueryType::AccelerationStructureSerializedSize: + queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR; + break; + default: + getDebugCallback()->handleMessage(DebugMessageType::Error, DebugMessageSource::Layer, + "Invalid query type for use in queryAccelerationStructureProperties."); + return; + } + auto queryPool = static_cast<QueryPoolImpl*>(queryDescs[i].queryPool)->m_pool; + m_commandBuffer->m_renderer->m_api.vkCmdResetQueryPool( + m_commandBuffer->m_commandBuffer, + queryPool, + (uint32_t)queryDescs[i].firstQueryIndex, + 1); + m_commandBuffer->m_renderer->m_api + .vkCmdWriteAccelerationStructuresPropertiesKHR( + m_commandBuffer->m_commandBuffer, + accelerationStructureCount, + vkHandlesView.getBuffer(), + queryType, + queryPool, + queryDescs[i].firstQueryIndex); + } + } + + virtual SLANG_NO_THROW void SLANG_MCALL buildAccelerationStructure( + const IAccelerationStructure::BuildDesc& desc, + int propertyQueryCount, + AccelerationStructureQueryDesc* queryDescs) override + { + AccelerationStructureBuildGeometryInfoBuilder geomInfoBuilder; + if (geomInfoBuilder.build(desc.inputs, getDebugCallback()) != SLANG_OK) + return; + + if (desc.dest) + { + geomInfoBuilder.buildInfo.dstAccelerationStructure = + static_cast<AccelerationStructureImpl*>(desc.dest)->m_vkHandle; + } + if (desc.source) + { + geomInfoBuilder.buildInfo.srcAccelerationStructure = + static_cast<AccelerationStructureImpl*>(desc.source)->m_vkHandle; + } + geomInfoBuilder.buildInfo.scratchData.deviceAddress = desc.scratchData; + + List<VkAccelerationStructureBuildRangeInfoKHR> rangeInfos; + rangeInfos.setCount(geomInfoBuilder.primitiveCounts.getCount()); + for (Index i = 0; i < geomInfoBuilder.primitiveCounts.getCount(); i++) + { + auto& rangeInfo = rangeInfos[i]; + rangeInfo.primitiveCount = geomInfoBuilder.primitiveCounts[i]; + rangeInfo.firstVertex = 0; + rangeInfo.primitiveOffset = 0; + rangeInfo.transformOffset = 0; + } + + auto rangeInfoPtr = rangeInfos.getBuffer(); + m_commandBuffer->m_renderer->m_api.vkCmdBuildAccelerationStructuresKHR( + m_commandBuffer->m_commandBuffer, 1, &geomInfoBuilder.buildInfo, &rangeInfoPtr); + + if (propertyQueryCount) + { + _memoryBarrier(1, &desc.dest, AccessFlag::Write, AccessFlag::Read); + _queryAccelerationStructureProperties( + 1, &desc.dest, propertyQueryCount, queryDescs); + } + } + + virtual SLANG_NO_THROW void SLANG_MCALL copyAccelerationStructure( + IAccelerationStructure* dest, + IAccelerationStructure* src, + AccelerationStructureCopyMode mode) override + { + VkCopyAccelerationStructureInfoKHR copyInfo = { + VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR}; + copyInfo.src = static_cast<AccelerationStructureImpl*>(src)->m_vkHandle; + copyInfo.dst = static_cast<AccelerationStructureImpl*>(dest)->m_vkHandle; + switch (mode) + { + case AccelerationStructureCopyMode::Clone: + copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR; + break; + case AccelerationStructureCopyMode::Compact: + copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR; + break; + default: + getDebugCallback()->handleMessage( + DebugMessageType::Error, + DebugMessageSource::Layer, + "Unsupported AccelerationStructureCopyMode."); + return; + } + m_commandBuffer->m_renderer->m_api.vkCmdCopyAccelerationStructureKHR( + m_commandBuffer->m_commandBuffer, ©Info); + } + + virtual SLANG_NO_THROW void SLANG_MCALL queryAccelerationStructureProperties( + int accelerationStructureCount, + IAccelerationStructure* const* accelerationStructures, + int queryCount, + AccelerationStructureQueryDesc* queryDescs) override + { + _queryAccelerationStructureProperties( + accelerationStructureCount, accelerationStructures, queryCount, queryDescs); + } + + virtual SLANG_NO_THROW void SLANG_MCALL serializeAccelerationStructure( + DeviceAddress dest, + IAccelerationStructure* source) override + { + VkCopyAccelerationStructureToMemoryInfoKHR copyInfo = { + VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR}; + copyInfo.src = static_cast<AccelerationStructureImpl*>(source)->m_vkHandle; + copyInfo.dst.deviceAddress = dest; + copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR; + m_commandBuffer->m_renderer->m_api.vkCmdCopyAccelerationStructureToMemoryKHR( + m_commandBuffer->m_commandBuffer, ©Info); + } + + virtual SLANG_NO_THROW void SLANG_MCALL deserializeAccelerationStructure( + IAccelerationStructure* dest, + DeviceAddress source) override + { + VkCopyMemoryToAccelerationStructureInfoKHR copyInfo = { + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR}; + copyInfo.src.deviceAddress = source; + copyInfo.dst = static_cast<AccelerationStructureImpl*>(dest)->m_vkHandle; + copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR; + m_commandBuffer->m_renderer->m_api.vkCmdCopyMemoryToAccelerationStructureKHR( + m_commandBuffer->m_commandBuffer, ©Info); + } + + virtual SLANG_NO_THROW void memoryBarrier( + int count, + IAccelerationStructure* const* structures, + AccessFlag::Enum srcAccess, + AccessFlag::Enum destAccess) override + { + _memoryBarrier(count, structures, srcAccess, destAccess); + } + + virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override + { + } + + virtual SLANG_NO_THROW void SLANG_MCALL + writeTimestamp(IQueryPool* queryPool, SlangInt index) override + { + _writeTimestamp( + &m_commandBuffer->m_renderer->m_api, + m_commandBuffer->m_commandBuffer, + queryPool, + index); + } + }; + + RefPtr<RayTracingCommandEncoder> m_rayTracingCommandEncoder; + + virtual SLANG_NO_THROW void SLANG_MCALL + encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override + { + if (!m_rayTracingCommandEncoder) + { + if (m_renderer->m_api.vkCmdBuildAccelerationStructuresKHR) + { + m_rayTracingCommandEncoder = new RayTracingCommandEncoder(); + m_rayTracingCommandEncoder->init(this); + } + } + *outEncoder = m_rayTracingCommandEncoder.Ptr(); + } + virtual SLANG_NO_THROW void SLANG_MCALL close() override { auto& vkAPI = m_renderer->m_api; @@ -4052,9 +4360,9 @@ public: RefPtr<VKDevice> m_renderer; VkQueue m_queue; uint32_t m_queueFamilyIndex; - VkSemaphore m_pendingWaitSemaphore = VK_NULL_HANDLE; + VkSemaphore m_pendingWaitSemaphores[2] = {VK_NULL_HANDLE, VK_NULL_HANDLE}; List<VkCommandBuffer> m_submitCommandBuffers; - static const int kSemaphoreCount = 2; + static const int kSemaphoreCount = 32; uint32_t m_currentSemaphoreIndex; VkSemaphore m_semaphores[kSemaphoreCount]; ~CommandQueueImpl() @@ -4114,26 +4422,37 @@ public: auto vkCmdBuf = cmdBufImpl->m_commandBuffer; m_submitCommandBuffers.add(vkCmdBuf); } - VkSemaphore waitSemaphore = m_pendingWaitSemaphore; VkSemaphore signalSemaphore = m_semaphores[m_currentSemaphoreIndex]; VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - VkPipelineStageFlags stageFlag = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - submitInfo.pWaitDstStageMask = &stageFlag; + VkPipelineStageFlags stageFlag[] = { + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT}; + submitInfo.pWaitDstStageMask = stageFlag; submitInfo.commandBufferCount = (uint32_t)m_submitCommandBuffers.getCount(); submitInfo.pCommandBuffers = m_submitCommandBuffers.getBuffer(); - if (m_pendingWaitSemaphore != VK_NULL_HANDLE) + Array<VkSemaphore, 2> waitSemaphores; + for (auto s : m_pendingWaitSemaphores) + { + if (s != VK_NULL_HANDLE) + { + waitSemaphores.add(s); + } + } + submitInfo.waitSemaphoreCount = (uint32_t)waitSemaphores.getCount(); + if (submitInfo.waitSemaphoreCount) { - submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = &waitSemaphore; + submitInfo.pWaitSemaphores = waitSemaphores.getBuffer(); } submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &signalSemaphore; - auto fence = static_cast<CommandBufferImpl*>(commandBuffers[0])->m_fence; + auto commandBufferImpl = static_cast<CommandBufferImpl*>(commandBuffers[0]); + auto fence = commandBufferImpl->m_transientHeap->getCurrentFence(); vkAPI.vkResetFences(vkAPI.m_device, 1, &fence); vkAPI.vkQueueSubmit(m_queue, 1, &submitInfo, fence); - m_pendingWaitSemaphore = signalSemaphore; + m_pendingWaitSemaphores[0] = signalSemaphore; + m_pendingWaitSemaphores[1] = VK_NULL_HANDLE; + commandBufferImpl->m_transientHeap->advanceFence(); m_currentSemaphoreIndex++; m_currentSemaphoreIndex = m_currentSemaphoreIndex % kSemaphoreCount; @@ -4149,16 +4468,37 @@ public: public: VkCommandPool m_commandPool; DescriptorSetAllocator m_descSetAllocator; - VkFence m_fence; + List<VkFence> m_fences; + Index m_fenceIndex = -1; List<RefPtr<CommandBufferImpl>> m_commandBufferPool; uint32_t m_commandBufferAllocId = 0; + VkFence getCurrentFence() + { + return m_fences[m_fenceIndex]; + } + void advanceFence() + { + m_fenceIndex++; + if (m_fenceIndex >= m_fences.getCount()) + { + m_fences.setCount(m_fenceIndex + 1); + VkFenceCreateInfo fenceCreateInfo = {}; + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + m_device->m_api.vkCreateFence( + m_device->m_api.m_device, &fenceCreateInfo, nullptr, &m_fences[m_fenceIndex]); + } + } Result init(const ITransientResourceHeap::Desc& desc, VKDevice* device); ~TransientResourceHeapImpl() { m_commandBufferPool = decltype(m_commandBufferPool)(); m_device->m_api.vkDestroyCommandPool(m_device->m_api.m_device, m_commandPool, nullptr); - m_device->m_api.vkDestroyFence(m_device->m_api.m_device, m_fence, nullptr); + for (auto fence : m_fences) + { + m_device->m_api.vkDestroyFence(m_device->m_api.m_device, fence, nullptr); + } m_descSetAllocator.close(); } public: @@ -4191,6 +4531,12 @@ public: case QueryType::Timestamp: createInfo.queryType = VK_QUERY_TYPE_TIMESTAMP; break; + case QueryType::AccelerationStructureCompactedSize: + createInfo.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR; + break; + case QueryType::AccelerationStructureSerializedSize: + createInfo.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR; + break; default: return SLANG_E_INVALID_ARG; } @@ -4554,13 +4900,22 @@ public: presentInfo.swapchainCount = 1; presentInfo.pSwapchains = &m_swapChain; presentInfo.pImageIndices = swapChainIndices; - if (m_queue->m_pendingWaitSemaphore != VK_NULL_HANDLE) + Array<VkSemaphore, 2> waitSemaphores; + for (auto s : m_queue->m_pendingWaitSemaphores) { - presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = &m_queue->m_pendingWaitSemaphore; + if (s != VK_NULL_HANDLE) + { + waitSemaphores.add(s); + } + } + presentInfo.waitSemaphoreCount = (uint32_t)waitSemaphores.getCount(); + if (presentInfo.waitSemaphoreCount) + { + presentInfo.pWaitSemaphores = waitSemaphores.getBuffer(); } m_api->vkQueuePresentKHR(m_queue->m_queue, &presentInfo); - m_queue->m_pendingWaitSemaphore = VK_NULL_HANDLE; + m_queue->m_pendingWaitSemaphores[0] = VK_NULL_HANDLE; + m_queue->m_pendingWaitSemaphores[1] = VK_NULL_HANDLE; return SLANG_OK; } virtual SLANG_NO_THROW int SLANG_MCALL acquireNextImage() override @@ -4584,7 +4939,7 @@ public: return m_currentImageIndex; } // Make the queue's next submit wait on `m_nextImageSemaphore`. - m_queue->m_pendingWaitSemaphore = m_nextImageSemaphore; + m_queue->m_pendingWaitSemaphores[1] = m_nextImageSemaphore; return m_currentImageIndex; } }; @@ -4730,7 +5085,6 @@ Result VKDevice::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBufferU VkBufferCreateInfo bufferCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; bufferCreateInfo.size = bufferSize; bufferCreateInfo.usage = usage; - SLANG_VK_CHECK(api.vkCreateBuffer(api.m_device, &bufferCreateInfo, nullptr, &m_buffer)); VkMemoryRequirements memoryReqs = {}; @@ -4744,7 +5098,14 @@ Result VKDevice::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBufferU VkMemoryAllocateInfo allocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; allocateInfo.allocationSize = memoryReqs.size; allocateInfo.memoryTypeIndex = memoryTypeIndex; - + VkMemoryAllocateFlagsInfo flagInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO}; + if (usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) + { + flagInfo.deviceMask = 1; + flagInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT; + allocateInfo.pNext = &flagInfo; + } + SLANG_VK_CHECK(api.vkAllocateMemory(api.m_device, &allocateInfo, nullptr, &m_memory)); SLANG_VK_CHECK(api.vkBindBufferMemory(api.m_device, m_buffer, m_memory, 0)); @@ -5042,24 +5403,6 @@ Result VKDevice::initVulkanInstanceAndDevice(bool useValidationLayer) const uint32_t majorVersion = VK_VERSION_MAJOR(basicProps.apiVersion); const uint32_t minorVersion = VK_VERSION_MINOR(basicProps.apiVersion); - // 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 }; - // 16 bit storage features - VkPhysicalDevice16BitStorageFeatures storage16BitFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_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 }; - // Timeline Semaphore features - VkPhysicalDeviceTimelineSemaphoreFeatures timelineFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES }; - // Extended dynamic state features - VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT }; - // Subgroup extended type features - VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures shaderSubgroupExtendedTypeFeatures = { - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES}; - // 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 && @@ -5069,6 +5412,18 @@ Result VKDevice::initVulkanInstanceAndDevice(bool useValidationLayer) VkPhysicalDeviceFeatures2 deviceFeatures2 = {}; deviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + // Buffer device address features + bufferDeviceAddressFeatures.pNext = deviceFeatures2.pNext; + deviceFeatures2.pNext = &bufferDeviceAddressFeatures; + + // Ray query features + rayQueryFeatures.pNext = deviceFeatures2.pNext; + deviceFeatures2.pNext = &rayQueryFeatures; + + // Acceleration structure features + accelerationStructureFeatures.pNext = deviceFeatures2.pNext; + deviceFeatures2.pNext = &accelerationStructureFeatures; + // Subgroup features shaderSubgroupExtendedTypeFeatures.pNext = deviceFeatures2.pNext; deviceFeatures2.pNext = &shaderSubgroupExtendedTypeFeatures; @@ -5174,6 +5529,31 @@ Result VKDevice::initVulkanInstanceAndDevice(bool useValidationLayer) deviceExtensions.add(VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME); m_features.add("shader-subgroup-extended-types"); } + + if (accelerationStructureFeatures.accelerationStructure) + { + accelerationStructureFeatures.pNext = (void*)deviceCreateInfo.pNext; + deviceCreateInfo.pNext = &accelerationStructureFeatures; + deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); + deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); + m_features.add("acceleration-structure"); + } + + if (rayQueryFeatures.rayQuery) + { + rayQueryFeatures.pNext = (void*)deviceCreateInfo.pNext; + deviceCreateInfo.pNext = &rayQueryFeatures; + deviceExtensions.add(VK_KHR_RAY_QUERY_EXTENSION_NAME); + m_features.add("ray-query"); + } + + if (bufferDeviceAddressFeatures.bufferDeviceAddress) + { + bufferDeviceAddressFeatures.pNext = (void*)deviceCreateInfo.pNext; + deviceCreateInfo.pNext = &bufferDeviceAddressFeatures; + deviceExtensions.add(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + m_features.add("buffer-device-address"); + } } m_queueFamilyIndex = m_api.findQueue(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT); @@ -5255,11 +5635,7 @@ Result VKDevice::TransientResourceHeapImpl::init( device->m_api.vkCreateCommandPool( device->m_api.m_device, &poolCreateInfo, nullptr, &m_commandPool); - VkFenceCreateInfo fenceCreateInfo = {}; - fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - device->m_api.vkCreateFence(device->m_api.m_device, &fenceCreateInfo, nullptr, &m_fence); - + advanceFence(); return SLANG_OK; } @@ -5276,7 +5652,7 @@ Result VKDevice::TransientResourceHeapImpl::createCommandBuffer(ICommandBuffer** RefPtr<CommandBufferImpl> commandBuffer = new CommandBufferImpl(); SLANG_RETURN_ON_FAIL(commandBuffer->init( - m_device, m_commandPool, m_fence, this)); + m_device, m_commandPool, this)); m_commandBufferPool.add(commandBuffer); m_commandBufferAllocId++; returnComPtr(outCmdBuffer, commandBuffer); @@ -5287,12 +5663,15 @@ Result VKDevice::TransientResourceHeapImpl::synchronizeAndReset() { m_commandBufferAllocId = 0; auto& api = m_device->m_api; - if (api.vkWaitForFences(api.m_device, 1, &m_fence, 1, UINT64_MAX) != VK_SUCCESS) + if (api.vkWaitForFences( + api.m_device, (uint32_t)m_fences.getCount(), m_fences.getBuffer(), 1, UINT64_MAX) != + VK_SUCCESS) { return SLANG_FAIL; } api.vkResetCommandPool(api.m_device, m_commandPool, 0); m_descSetAllocator.reset(); + m_fenceIndex = 0; Super::reset(); return SLANG_OK; } @@ -5421,6 +5800,69 @@ SlangResult VKDevice::readBufferResource( return SLANG_OK; } +Result VKDevice::getAccelerationStructurePrebuildInfo( + const IAccelerationStructure::BuildInputs& buildInputs, + IAccelerationStructure::PrebuildInfo* outPrebuildInfo) +{ + if (!m_api.vkGetAccelerationStructureBuildSizesKHR) + { + return SLANG_E_NOT_AVAILABLE; + } + VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR}; + AccelerationStructureBuildGeometryInfoBuilder geomInfoBuilder; + SLANG_RETURN_ON_FAIL(geomInfoBuilder.build(buildInputs, getDebugCallback())); + m_api.vkGetAccelerationStructureBuildSizesKHR( + m_api.m_device, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, + &geomInfoBuilder.buildInfo, + geomInfoBuilder.primitiveCounts.getBuffer(), + &sizeInfo); + outPrebuildInfo->resultDataMaxSize = sizeInfo.accelerationStructureSize; + outPrebuildInfo->scratchDataSize = sizeInfo.buildScratchSize; + outPrebuildInfo->updateScratchDataSize = sizeInfo.updateScratchSize; + return SLANG_OK; +} + +Result VKDevice::createAccelerationStructure( + const IAccelerationStructure::CreateDesc& desc, + IAccelerationStructure** outAS) +{ + if (!m_api.vkCreateAccelerationStructureKHR) + { + return SLANG_E_NOT_AVAILABLE; + } + RefPtr<AccelerationStructureImpl> resultAS = new AccelerationStructureImpl(); + resultAS->m_offset = desc.offset; + resultAS->m_size = desc.size; + resultAS->m_buffer = static_cast<BufferResourceImpl*>(desc.buffer); + resultAS->m_device = this; + VkAccelerationStructureCreateInfoKHR createInfo = {VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR}; + createInfo.buffer = resultAS->m_buffer->m_buffer.m_buffer; + createInfo.offset = desc.offset; + createInfo.size = desc.size; + switch (desc.kind) + { + case IAccelerationStructure::Kind::BottomLevel: + createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; + break; + case IAccelerationStructure::Kind::TopLevel: + createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + break; + default: + getDebugCallback()->handleMessage( + DebugMessageType::Error, + DebugMessageSource::Layer, + "invalid value of IAccelerationStructure::Kind encountered in desc.kind"); + return SLANG_E_INVALID_ARG; + } + + SLANG_VK_RETURN_ON_FAIL(m_api.vkCreateAccelerationStructureKHR( + m_api.m_device, &createInfo, nullptr, &resultAS->m_vkHandle)); + returnComPtr(outAS, resultAS); + return SLANG_OK; +} + static VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceState state) { switch (state) @@ -5448,6 +5890,8 @@ static VkBufferUsageFlagBits _calcBufferUsageFlags(ResourceState state) return VK_BUFFER_USAGE_TRANSFER_SRC_BIT; case ResourceState::CopyDestination: return VK_BUFFER_USAGE_TRANSFER_DST_BIT; + case ResourceState::AccelerationStructure: + return VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR; default: return VkBufferUsageFlagBits(0); } @@ -5510,7 +5954,7 @@ static VkImageUsageFlags _calcImageUsageFlags( { VkImageUsageFlags usage = _calcImageUsageFlags(states); - if ((cpuAccessFlags & IResource::AccessFlag::Write) || initData) + if ((cpuAccessFlags & AccessFlag::Write) || initData) { usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; } @@ -5626,6 +6070,15 @@ void VKDevice::_transitionImageLayout(VkImage image, VkFormat format, const Text sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; } + else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && + newLayout == VK_IMAGE_LAYOUT_GENERAL) + { + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; + + sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + } else { assert(!"unsupported layout transition!"); @@ -5902,6 +6355,10 @@ Result VKDevice::createBufferResource(const IBufferResource::Desc& descIn, const VkMemoryPropertyFlags reqMemoryProperties = 0; VkBufferUsageFlags usage = _calcBufferUsageFlags(desc.allowedStates); + if (bufferDeviceAddressFeatures.bufferDeviceAddress) + { + usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + } if (initData) { @@ -5916,7 +6373,7 @@ Result VKDevice::createBufferResource(const IBufferResource::Desc& descIn, const RefPtr<BufferResourceImpl> buffer(new BufferResourceImpl(desc, this)); SLANG_RETURN_ON_FAIL(buffer->m_buffer.init(m_api, desc.sizeInBytes, usage, reqMemoryProperties)); - if ((desc.cpuAccessFlags & IResource::AccessFlag::Write) || initData) + if ((desc.cpuAccessFlags & AccessFlag::Write) || initData) { SLANG_RETURN_ON_FAIL(buffer->m_uploadBuffer.init(m_api, bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)); } diff --git a/tools/gfx/vulkan/vk-api.h b/tools/gfx/vulkan/vk-api.h index 4c024525b..5d044944f 100644 --- a/tools/gfx/vulkan/vk-api.h +++ b/tools/gfx/vulkan/vk-api.h @@ -159,7 +159,14 @@ namespace gfx { x(vkGetBufferDeviceAddress) \ x(vkGetBufferDeviceAddressKHR) \ x(vkGetBufferDeviceAddressEXT) \ - + x(vkCmdBuildAccelerationStructuresKHR) \ + x(vkCmdCopyAccelerationStructureKHR) \ + x(vkCmdCopyAccelerationStructureToMemoryKHR) \ + x(vkCmdCopyMemoryToAccelerationStructureKHR) \ + x(vkCmdWriteAccelerationStructuresPropertiesKHR) \ + x(vkCreateAccelerationStructureKHR) \ + x(vkDestroyAccelerationStructureKHR) \ + x(vkGetAccelerationStructureBuildSizesKHR) \ /* */ #define VK_API_ALL_GLOBAL_PROCS(x) \ diff --git a/tools/gfx/vulkan/vk-util.cpp b/tools/gfx/vulkan/vk-util.cpp index 5f7077753..4971e3f3d 100644 --- a/tools/gfx/vulkan/vk-util.cpp +++ b/tools/gfx/vulkan/vk-util.cpp @@ -1,5 +1,6 @@ // vk-util.cpp #include "vk-util.h" +#include "core/slang-math.h" #include <stdlib.h> #include <stdio.h> @@ -170,4 +171,145 @@ VkImageLayout VulkanUtil::mapResourceStateToLayout(ResourceState state) } } -} // renderer_test +Result AccelerationStructureBuildGeometryInfoBuilder::build( + const IAccelerationStructure::BuildInputs& buildInputs, + IDebugCallback* debugCallback) +{ + buildInfo.dstAccelerationStructure = VK_NULL_HANDLE; + switch (buildInputs.kind) + { + case IAccelerationStructure::Kind::BottomLevel: + buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; + break; + case IAccelerationStructure::Kind::TopLevel: + buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + break; + default: + debugCallback->handleMessage( + DebugMessageType::Error, + DebugMessageSource::Layer, + "invalid value of IAccelerationStructure::Kind encountered in buildInputs.kind"); + return SLANG_E_INVALID_ARG; + } + if (buildInputs.flags & IAccelerationStructure::BuildFlags::Enum::PerformUpdate) + { + buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR; + } + else + { + buildInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR; + } + if (buildInputs.flags & IAccelerationStructure::BuildFlags::Enum::AllowCompaction) + { + buildInfo.flags |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR; + } + if (buildInputs.flags & IAccelerationStructure::BuildFlags::Enum::AllowUpdate) + { + buildInfo.flags |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR; + } + if (buildInputs.flags & IAccelerationStructure::BuildFlags::Enum::MinimizeMemory) + { + buildInfo.flags |= VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR; + } + if (buildInputs.flags & IAccelerationStructure::BuildFlags::Enum::PreferFastBuild) + { + buildInfo.flags |= VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR; + } + if (buildInputs.flags & IAccelerationStructure::BuildFlags::Enum::PreferFastTrace) + { + buildInfo.flags |= VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; + } + if (buildInputs.kind == IAccelerationStructure::Kind::BottomLevel) + { + m_geometryInfos.setCount(buildInputs.descCount); + primitiveCounts.setCount(buildInputs.descCount); + memset( + m_geometryInfos.getBuffer(), + 0, + sizeof(VkAccelerationStructureGeometryKHR) * buildInputs.descCount); + for (int i = 0; i < buildInputs.descCount; i++) + { + auto& geomDesc = buildInputs.geometryDescs[i]; + m_geometryInfos[i].sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + if (geomDesc.flags & IAccelerationStructure::GeometryFlags::NoDuplicateAnyHitInvocation) + { + m_geometryInfos[i].flags |= VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR; + } + else if (geomDesc.flags & IAccelerationStructure::GeometryFlags::Opaque) + { + m_geometryInfos[i].flags |= VK_GEOMETRY_OPAQUE_BIT_KHR; + } + auto& vkGeomData = m_geometryInfos[i].geometry; + switch (geomDesc.type) + { + case IAccelerationStructure::GeometryType::Triangles: + m_geometryInfos[i].geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; + vkGeomData.triangles.sType = + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; + vkGeomData.triangles.vertexFormat = + VulkanUtil::getVkFormat(geomDesc.content.triangles.vertexFormat); + vkGeomData.triangles.vertexData.deviceAddress = + geomDesc.content.triangles.vertexData; + vkGeomData.triangles.vertexStride = geomDesc.content.triangles.vertexStride; + vkGeomData.triangles.maxVertex = geomDesc.content.triangles.vertexCount - 1; + switch (geomDesc.content.triangles.indexFormat) + { + case Format::R_UInt32: + vkGeomData.triangles.indexType = VK_INDEX_TYPE_UINT32; + break; + case Format::R_UInt16: + vkGeomData.triangles.indexType = VK_INDEX_TYPE_UINT16; + break; + default: + debugCallback->handleMessage( + DebugMessageType::Error, + DebugMessageSource::Layer, + "unsupported value of Format encountered in " + "GeometryDesc::content.triangles.indexFormat"); + return SLANG_E_INVALID_ARG; + } + vkGeomData.triangles.indexData.deviceAddress = geomDesc.content.triangles.indexData; + vkGeomData.triangles.transformData.deviceAddress = + geomDesc.content.triangles.transform3x4; + primitiveCounts[i] = Slang::Math::Max( + geomDesc.content.triangles.vertexCount, + geomDesc.content.triangles.indexCount) / + 3; + break; + case IAccelerationStructure::GeometryType::ProcedurePrimitives: + m_geometryInfos[i].geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; + vkGeomData.aabbs.sType = + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR; + vkGeomData.aabbs.data.deviceAddress = geomDesc.content.proceduralAABBs.data; + vkGeomData.aabbs.stride = geomDesc.content.proceduralAABBs.stride; + primitiveCounts[i] = + (uint32_t)buildInputs.geometryDescs[i].content.proceduralAABBs.count; + break; + default: + debugCallback->handleMessage( + DebugMessageType::Error, + DebugMessageSource::Layer, + "invalid value of IAccelerationStructure::GeometryType encountered in " + "buildInputs.geometryDescs"); + return SLANG_E_INVALID_ARG; + } + } + buildInfo.geometryCount = buildInputs.descCount; + buildInfo.pGeometries = m_geometryInfos.getBuffer(); + } + else + { + m_vkInstanceInfo.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; + m_vkInstanceInfo.geometry.instances.sType = + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR; + m_vkInstanceInfo.geometry.instances.arrayOfPointers = 0; + m_vkInstanceInfo.geometry.instances.data.deviceAddress = buildInputs.instanceDescs; + buildInfo.pGeometries = &m_vkInstanceInfo; + buildInfo.geometryCount = 1; + primitiveCounts.setCount(1); + primitiveCounts[0] = buildInputs.descCount; + } + return SLANG_OK; +} + +} // namespace gfx diff --git a/tools/gfx/vulkan/vk-util.h b/tools/gfx/vulkan/vk-util.h index a39fe5115..450e78ebd 100644 --- a/tools/gfx/vulkan/vk-util.h +++ b/tools/gfx/vulkan/vk-util.h @@ -1,6 +1,7 @@ // vk-util.h #pragma once +#include "core/slang-basic.h" #include "vk-api.h" #include "slang-gfx.h" @@ -46,4 +47,22 @@ struct VulkanUtil static VkImageLayout getImageLayoutFromState(ResourceState state); }; +struct AccelerationStructureBuildGeometryInfoBuilder +{ +public: + VkAccelerationStructureBuildGeometryInfoKHR buildInfo = { + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR}; + Slang::List<uint32_t> primitiveCounts; + + Slang::Result build( + const IAccelerationStructure::BuildInputs& buildInputs, + IDebugCallback* debugCallback); + +private: + Slang::List<VkAccelerationStructureGeometryKHR> m_geometryInfos; + VkAccelerationStructureGeometryKHR m_vkInstanceInfo = { + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR}; +}; + + } // renderer_test diff --git a/tools/platform/gui.cpp b/tools/platform/gui.cpp index ba6fc35f8..e4f269b95 100644 --- a/tools/platform/gui.cpp +++ b/tools/platform/gui.cpp @@ -216,7 +216,7 @@ void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuf vertexBufferDesc.allowedStates = ResourceStateSet(ResourceState::VertexBuffer, ResourceState::CopyDestination); vertexBufferDesc.sizeInBytes = vertexCount * sizeof(ImDrawVert); - vertexBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; + vertexBufferDesc.cpuAccessFlags = AccessFlag::Write; auto vertexBuffer = device->createBufferResource(vertexBufferDesc); gfx::IBufferResource::Desc indexBufferDesc; @@ -225,7 +225,7 @@ void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuf indexBufferDesc.allowedStates = ResourceStateSet(ResourceState::IndexBuffer, ResourceState::CopyDestination); indexBufferDesc.defaultState = ResourceState::IndexBuffer; - indexBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; + indexBufferDesc.cpuAccessFlags = AccessFlag::Write; auto indexBuffer = device->createBufferResource(indexBufferDesc); auto cmdBuf = transientHeap->createCommandBuffer(); auto encoder = cmdBuf->encodeResourceCommands(); @@ -253,7 +253,7 @@ void GUI::endFrame(ITransientResourceHeap* transientHeap, IFramebuffer* framebuf ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination); constantBufferDesc.defaultState = ResourceState::ConstantBuffer; constantBufferDesc.sizeInBytes = sizeof(glm::mat4x4); - constantBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; + constantBufferDesc.cpuAccessFlags = AccessFlag::Write; auto constantBuffer = device->createBufferResource(constantBufferDesc); { diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index a846f4a33..03662a480 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -435,9 +435,7 @@ Result RenderTestApp::applyBinding(PipelineType pipelineType, ICommandEncoder* e { case PipelineType::Compute: { - ComPtr<IComputeCommandEncoder> computeEncoder; - encoder->queryInterface( - SLANG_UUID_IComputeCommandEncoder, (void**)computeEncoder.writeRef()); + 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)); @@ -445,9 +443,7 @@ Result RenderTestApp::applyBinding(PipelineType pipelineType, ICommandEncoder* e break; case PipelineType::Graphics: { - ComPtr<IRenderCommandEncoder> renderEncoder; - encoder->queryInterface( - SLANG_UUID_IRenderCommandEncoder, (void**)renderEncoder.writeRef()); + 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)); @@ -523,7 +519,7 @@ SlangResult RenderTestApp::initialize( IBufferResource::Desc vertexBufferDesc; vertexBufferDesc.type = IResource::Type::Buffer; vertexBufferDesc.sizeInBytes = kVertexCount * sizeof(Vertex); - vertexBufferDesc.cpuAccessFlags = IResource::AccessFlag::Write; + vertexBufferDesc.cpuAccessFlags = AccessFlag::Write; vertexBufferDesc.defaultState = ResourceState::VertexBuffer; vertexBufferDesc.allowedStates = ResourceStateSet(ResourceState::VertexBuffer); @@ -697,7 +693,7 @@ Result RenderTestApp::writeBindingOutput(const String& fileName) const size_t bufferSize = bufferDesc.sizeInBytes; ComPtr<ISlangBlob> blob; - if(bufferDesc.cpuAccessFlags & IResource::AccessFlag::Read) + if(bufferDesc.cpuAccessFlags & AccessFlag::Read) { // The buffer is already allocated for CPU access, so we can read it back directly. // @@ -708,7 +704,7 @@ Result RenderTestApp::writeBindingOutput(const String& fileName) // The buffer is not CPU-readable, so we will copy it using a staging buffer. auto stagingBufferDesc = bufferDesc; - stagingBufferDesc.cpuAccessFlags = IResource::AccessFlag::Read; + stagingBufferDesc.cpuAccessFlags = AccessFlag::Read; stagingBufferDesc.allowedStates = ResourceStateSet(ResourceState::CopyDestination, ResourceState::CopySource); stagingBufferDesc.defaultState = ResourceState::CopyDestination; @@ -720,8 +716,8 @@ Result RenderTestApp::writeBindingOutput(const String& fileName) SLANG_RETURN_ON_FAIL( m_transientHeap->createCommandBuffer(commandBuffer.writeRef())); - ComPtr<IResourceCommandEncoder> encoder; - commandBuffer->encodeResourceCommands(encoder.writeRef()); + IResourceCommandEncoder* encoder = nullptr; + commandBuffer->encodeResourceCommands(&encoder); encoder->copyBuffer(stagingBuffer, 0, bufferResource, 0, bufferSize); encoder->endEncoding(); |
