Skip to content

Commit

Permalink
WebGPU: Added query (close #531)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikhailGorobets committed Aug 2, 2024
1 parent a7e8639 commit 61fd532
Show file tree
Hide file tree
Showing 15 changed files with 514 additions and 127 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ jobs:
uses: DiligentGraphics/github-action/run-core-gpu-tests@v1
with:
mode: wgpu
args: --gtest_filter=-QueryTest.*

- name: Upload artifact
uses: actions/upload-artifact@v3
Expand Down
13 changes: 13 additions & 0 deletions Graphics/GraphicsEngine/interface/GraphicsTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -4128,6 +4128,19 @@ struct EngineWebGPUCreateInfo DILIGENT_DERIVE(EngineCreateInfo)
///
Uint32 DynamicHeapPageSize DEFAULT_INITIALIZER(256 << 10);

///
Uint32 QueryPoolSizes[QUERY_TYPE_NUM_TYPES]
#if DILIGENT_CPP_INTERFACE
{
0, // Ignored
128, // QUERY_TYPE_OCCLUSION
0, // QUERY_TYPE_BINARY_OCCLUSION
512, // QUERY_TYPE_TIMESTAMP
0, // QUERY_TYPE_PIPELINE_STATISTICS
256 // QUERY_TYPE_DURATION
}
#endif
;

#if DILIGENT_CPP_INTERFACE
EngineWebGPUCreateInfo() noexcept :
Expand Down
14 changes: 11 additions & 3 deletions Graphics/GraphicsEngineWebGPU/include/DeviceContextWebGPUImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,15 @@ class DeviceContextWebGPUImpl final : public DeviceContextBase<EngineWebGPUImplT
DEBUG_GROUP_TYPE_NULL
};

enum OCCLUSION_QUERY_TYPE : Uint32
{
// Occlusion query was started within render pass encoder
OCCLUSION_QUERY_TYPE_INNER,

// Occlusion query was started was started outside of render pass encoder
OCCLUSION_QUERY_TYPE_OUTER
};

WGPUCommandEncoder GetCommandEncoder();

WGPURenderPassEncoder GetRenderPassCommandEncoder();
Expand Down Expand Up @@ -582,6 +591,7 @@ class DeviceContextWebGPUImpl final : public DeviceContextBase<EngineWebGPUImplT
using DynamicMemoryPageList = std::vector<DynamicMemoryManagerWebGPU::Page>;
using MappedTextureCache = std::unordered_map<MappedTextureKey, MappedTexture, MappedTextureKey::Hasher>;
using DebugGroupStack = std::vector<DEBUG_GROUP_TYPE>;
using OcclusionQueryStack = std::vector<std::pair<OCCLUSION_QUERY_TYPE, Uint32>>;

WebGPUQueueWrapper m_wgpuQueue;
WebGPUCommandEncoderWrapper m_wgpuCommandEncoder;
Expand All @@ -597,9 +607,7 @@ class DeviceContextWebGPUImpl final : public DeviceContextBase<EngineWebGPUImplT
MappedTextureCache m_MappedTextures;
DebugGroupStack m_DebugGroupsStack;
DebugGroupStack m_PendingDebugGroups;

QueryManagerWebGPU* m_pQueryMgr = nullptr;
Int32 m_ActiveQueriesCounter = 0;
OcclusionQueryStack m_OcclusionQueriesStack;

RefCntAutoPtr<IFence> m_pFence;
Uint64 m_FenceValue = 0;
Expand Down
52 changes: 49 additions & 3 deletions Graphics/GraphicsEngineWebGPU/include/QueryManagerWebGPU.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,42 @@ class QueryManagerWebGPU
QueryManagerWebGPU& operator = ( QueryManagerWebGPU&&) = delete;
// clang-format on

static constexpr Uint32 InvalidIndex = static_cast<Uint32>(-1);
static constexpr Uint32 InvalidIndex = UINT32_MAX;

Uint32 AllocateQuery(QUERY_TYPE Type);

void ReleaseQuery(QUERY_TYPE Type, Uint32 Index);

WGPUQuerySet GetQuerySet(QUERY_TYPE Type) const;

Uint32 GetReadbackBufferIdentifier(QUERY_TYPE Type, Uint64 EventValue) const;

Uint64 GetQueryResult(QUERY_TYPE Type, Uint32 Index, Uint32 BufferIdentifier) const;

Uint64 GetNextEventValue(QUERY_TYPE Type);

void ResolveQuerySet(RenderDeviceWebGPUImpl* pDevice, WGPUCommandEncoder wgpuCmdEncoder);

void ReadbackQuerySet(RenderDeviceWebGPUImpl* pDevice);

void FinishFrame(RenderDeviceWebGPUImpl* pDevice);

void WaitAllQuerySet(RenderDeviceWebGPUImpl* pDevice);

private:
class QuerySetInfo
{
public:
struct ReadbackBufferInfo
{
WebGPUBufferWrapper ReadbackBuffer;
std::vector<Uint64> DataResult;
Uint32 BufferIdentifier;
Uint64 LastEventValue;
Uint64 PendingEventValue;
};
using ReadbackBufferList = std::vector<ReadbackBufferInfo>;

public:
QuerySetInfo() = default;

Expand All @@ -74,7 +99,7 @@ class QueryManagerWebGPU
QuerySetInfo& operator = ( QuerySetInfo&&) = delete;
// clang-format on

void Initialize(WGPUDevice wgpuDevice, const WGPUQuerySetDescriptor& wgpuQuerySetDesc, QUERY_TYPE Type);
void Initialize(RenderDeviceWebGPUImpl* pDevice, Uint32 HeapSize, QUERY_TYPE Type);

Uint32 Allocate();

Expand All @@ -84,24 +109,45 @@ class QueryManagerWebGPU

Uint32 GetQueryCount() const;

Uint64 GetQueryResult(Uint32 Index, Uint32 BufferIdentifier) const;

WGPUQuerySet GetWebGPUQuerySet() const;

Uint32 GetMaxAllocatedQueries() const;

bool IsNull() const;

Uint32 ResolveQueries(RenderDeviceWebGPUImpl* pDevice, WGPUCommandEncoder wgpuCmdEncoder);

void ReadbackQueries(RenderDeviceWebGPUImpl* pDevice, Uint32 PendingRedbackIndex);

void WaitAllQueries(RenderDeviceWebGPUImpl* pDevice, Uint32 PendingRedbackIndex);

ReadbackBufferInfo& FindAvailableReadbackBuffer(RenderDeviceWebGPUImpl* pDevice);

Uint32 GetReadbackBufferIdentifier(Uint64 EventValue) const;

Uint64 GetNextEventValue();

Uint64 IncrementEventValue();

private:
WebGPUQuerySetWrapper m_wgpuQuerySet;
WebGPUBufferWrapper m_wgpuResolveBuffer;
WebGPUBufferWrapper m_wgpuStagingBuffer;
std::vector<Uint32> m_AvailableQueries;
ReadbackBufferList m_PendingReadbackBuffers;

QUERY_TYPE m_Type = QUERY_TYPE_UNDEFINED;
Uint32 m_QueryCount = 0;
Uint32 m_MaxAllocatedQueries = 0;
Uint64 m_EventValue = 0;

static constexpr Uint32 MaxPendingBuffers = 16;
};

std::array<QuerySetInfo, QUERY_TYPE_NUM_TYPES> m_QuerySets;
std::array<Uint32, QUERY_TYPE_NUM_TYPES> m_PendingReadbackIndices;
Uint32 m_ActiveQuerySets = 0;
};

} // namespace Diligent
7 changes: 5 additions & 2 deletions Graphics/GraphicsEngineWebGPU/include/QueryWebGPUImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class QueryWebGPUImpl final : public QueryBase<EngineWebGPUImplTraits>
/// Implementation of IQuery::Invalidate().
void DILIGENT_CALL_TYPE Invalidate() override final;

Uint32 GetIndexInsideQuerySet(Uint32 QueryId) const;

bool OnBeginQuery(DeviceContextWebGPUImpl* pContext);

bool OnEndQuery(DeviceContextWebGPUImpl* pContext);
Expand All @@ -66,8 +68,9 @@ class QueryWebGPUImpl final : public QueryBase<EngineWebGPUImplTraits>
void ReleaseQueries();

private:
std::array<Uint32, 2> m_QuerySetIndex = {QueryManagerWebGPU::InvalidIndex, QueryManagerWebGPU::InvalidIndex};
QueryManagerWebGPU* m_pQueryMgr = nullptr;
std::array<Uint32, 2> m_QuerySetIndices = {QueryManagerWebGPU::InvalidIndex, QueryManagerWebGPU::InvalidIndex};
QueryManagerWebGPU* m_pQueryMgr = nullptr;
Uint64 m_QueryEventValue = 0;
};

} // namespace Diligent
11 changes: 6 additions & 5 deletions Graphics/GraphicsEngineWebGPU/include/RenderDeviceWebGPUImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,6 @@ class RenderDeviceWebGPUImpl final : public RenderDeviceBase<EngineWebGPUImplTra
RESOURCE_STATE InitialState,
IBuffer** ppBuffer) override final;

const WGPULimits& GetLimits() const { return m_wgpuLimits; }

public:
void CreatePipelineResourceSignature(const PipelineResourceSignatureDesc& Desc,
IPipelineResourceSignature** ppSignature,
Expand All @@ -195,6 +193,10 @@ class RenderDeviceWebGPUImpl final : public RenderDeviceBase<EngineWebGPUImplTra
ISampler** ppSampler,
bool IsDeviceInternal);

const WGPULimits& GetLimits() const { return m_wgpuLimits; }

QueryManagerWebGPU& GetQueryManager() { return *m_pQueryManager; }

Uint64 GetCommandQueueCount() const { return 1; }

Uint64 GetCommandQueueMask() const { return 1; }
Expand All @@ -212,7 +214,7 @@ class RenderDeviceWebGPUImpl final : public RenderDeviceBase<EngineWebGPUImplTra
return *m_pDynamicMemoryManager;
}

void PollEvents(bool YieldToWebBrowser);
void PollEvents();

private:
void TestTextureFormat(TEXTURE_FORMAT TexFormat) override;
Expand All @@ -230,8 +232,7 @@ class RenderDeviceWebGPUImpl final : public RenderDeviceBase<EngineWebGPUImplTra

AttachmentCleanerWebGPUPtr m_pAttachmentCleaner;
GenerateMipsHelperWebGPUPtr m_pMipsGenerator;

std::vector<QueryManagerWebGPUPtr> m_QueryMgrs;
QueryManagerWebGPUPtr m_pQueryManager;
};

} // namespace Diligent
4 changes: 2 additions & 2 deletions Graphics/GraphicsEngineWebGPU/src/BufferWebGPUImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ void BufferWebGPUImpl::Map(MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedD
m_MapState.State = BufferMapState::Read;
wgpuBufferMapAsync(m_wgpuBuffer.Get(), WGPUMapMode_Read, 0, StaticCast<size_t>(m_Desc.Size), MapAsyncCallback, this);
while (wgpuBufferGetMapState(m_wgpuBuffer.Get()) != WGPUBufferMapState_Unmapped)
m_pDevice->PollEvents(true);
m_pDevice->PollEvents();

pMappedData = m_MappedData.data();
}
Expand Down Expand Up @@ -321,7 +321,7 @@ void BufferWebGPUImpl::Unmap(MAP_TYPE MapType)

wgpuBufferMapAsync(m_wgpuBuffer.Get(), WGPUMapMode_Write, 0, StaticCast<size_t>(m_Desc.Size), MapAsyncCallback, this);
while (wgpuBufferGetMapState(m_wgpuBuffer.Get()) != WGPUBufferMapState_Unmapped)
m_pDevice->PollEvents(true);
m_pDevice->PollEvents();
}
else if (m_MapState.State == BufferMapState::ReadAsync || m_MapState.State == BufferMapState::WriteAsync)
{
Expand Down
Loading

0 comments on commit 61fd532

Please sign in to comment.