| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567 |
- /*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
- */
- #ifndef BGFX_RENDERER_WEBGPU_H_HEADER_GUARD
- #define BGFX_RENDERER_WEBGPU_H_HEADER_GUARD
- #include "bgfx_p.h"
- #if BGFX_CONFIG_RENDERER_WEBGPU
- #if !BX_PLATFORM_EMSCRIPTEN
- # include <dawn/webgpu_cpp.h>
- # include <dawn/dawn_wsi.h>
- #else
- # include <webgpu/webgpu_cpp.h>
- #endif // !BX_PLATFORM_EMSCRIPTEN
- #define BGFX_WEBGPU_PROFILER_BEGIN(_view, _abgr) \
- BX_MACRO_BLOCK_BEGIN \
- BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \
- BX_MACRO_BLOCK_END
- #define BGFX_WEBGPU_PROFILER_BEGIN_LITERAL(_name, _abgr) \
- BX_MACRO_BLOCK_BEGIN \
- BGFX_PROFILER_BEGIN_LITERAL("" # _name, _abgr); \
- BX_MACRO_BLOCK_END
- #define BGFX_WEBGPU_PROFILER_END() \
- BX_MACRO_BLOCK_BEGIN \
- BGFX_PROFILER_END(); \
- BX_MACRO_BLOCK_END
- #define WEBGPU_MAX_FRAMES_IN_FLIGHT 3
- #define WEBGPU_NUM_UNIFORM_BUFFERS 8
- namespace bgfx { namespace webgpu
- {
- template <typename Ty>
- class StateCacheT
- {
- public:
- void add(uint64_t _id, Ty _item)
- {
- invalidate(_id);
- m_hashMap.insert(stl::make_pair(_id, _item));
- }
- Ty find(uint64_t _id)
- {
- typename HashMap::iterator it = m_hashMap.find(_id);
- if(it != m_hashMap.end())
- {
- return it->second;
- }
- return NULL;
- }
- void invalidate(uint64_t _id)
- {
- typename HashMap::iterator it = m_hashMap.find(_id);
- if(it != m_hashMap.end())
- {
- release(it->second);
- m_hashMap.erase(it);
- }
- }
- void invalidate()
- {
- for(typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
- {
- release(it->second);
- }
- m_hashMap.clear();
- }
- uint32_t getCount() const
- {
- return uint32_t(m_hashMap.size());
- }
- private:
- typedef stl::unordered_map<uint64_t, Ty> HashMap;
- HashMap m_hashMap;
- };
- struct BufferWgpu
- {
- void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false);
- void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
- void destroy()
- {
- m_ptr.Destroy();
- if(NULL != m_dynamic)
- {
- BX_DELETE(g_allocator, m_dynamic);
- m_dynamic = NULL;
- }
- }
- uint32_t m_size;
- uint16_t m_flags = BGFX_BUFFER_NONE;
- bool m_vertex;
- String m_label;
- wgpu::Buffer m_ptr;
- uint8_t* m_dynamic = NULL;
- };
- typedef BufferWgpu IndexBufferWgpu;
- struct VertexBufferWgpu : public BufferWgpu
- {
- void create(uint32_t _size, void* _data, VertexLayoutHandle _declHandle, uint16_t _flags);
- VertexLayoutHandle m_layoutHandle;
- };
- struct BindInfo
- {
- uint32_t m_index = UINT32_MAX;
- uint32_t m_binding = UINT32_MAX;
- UniformHandle m_uniform = BGFX_INVALID_HANDLE;
- };
- struct ShaderWgpu
- {
- void create(ShaderHandle _handle, const Memory* _mem);
- void destroy()
- {
- if (NULL != m_constantBuffer)
- {
- UniformBuffer::destroy(m_constantBuffer);
- m_constantBuffer = NULL;
- }
- m_module = NULL;
- }
- const char* name() const { return getName(m_handle); }
- ShaderHandle m_handle;
- String m_label;
- wgpu::ShaderStage m_stage;
- wgpu::ShaderModule m_module;
- uint32_t* m_code = NULL;
- size_t m_codeSize = 0;
- UniformBuffer* m_constantBuffer = NULL;
- PredefinedUniform m_predefined[PredefinedUniform::Count];
- uint16_t m_attrMask[Attrib::Count];
- uint8_t m_attrRemap[Attrib::Count];
- uint32_t m_hash = 0;
- uint16_t m_numUniforms = 0;
- uint16_t m_size = 0;
- uint16_t m_gpuSize = 0;
- uint8_t m_numPredefined = 0;
- uint8_t m_numAttrs = 0;
- BindInfo m_bindInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
- wgpu::BindGroupLayoutEntry m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
- wgpu::BindGroupLayoutEntry m_textures[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
- uint8_t m_numSamplers = 0;
- wgpu::BindGroupLayoutEntry m_buffers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
- uint32_t m_numBuffers = 0;
- };
- struct PipelineStateWgpu;
- struct ProgramWgpu
- {
- void create(const ShaderWgpu* _vsh, const ShaderWgpu* _fsh);
- void destroy();
- const ShaderWgpu* m_vsh = NULL;
- const ShaderWgpu* m_fsh = NULL;
- PredefinedUniform m_predefined[PredefinedUniform::Count * 2];
- uint8_t m_numPredefined;
- PipelineStateWgpu* m_computePS = NULL;
- wgpu::BindGroupLayout m_bindGroupLayout;
- uint16_t m_gpuSize = 0;
- uint32_t m_numUniforms;
- uint32_t m_bindGroupLayoutHash;
- BindInfo m_bindInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
- wgpu::BindGroupLayoutEntry m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
- wgpu::BindGroupLayoutEntry m_textures[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
- uint32_t m_numSamplers = 0;
- wgpu::BindGroupLayoutEntry m_buffers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
- uint32_t m_numBuffers = 0;
- };
- constexpr size_t kMaxVertexInputs = 16;
- constexpr size_t kMaxVertexAttributes = 16;
- constexpr size_t kMaxColorAttachments = BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS;
- constexpr uint32_t kMinBufferOffsetAlignment = 256;
- struct RenderPassDescriptor
- {
- RenderPassDescriptor();
- wgpu::RenderPassDescriptor desc;
- wgpu::RenderPassColorAttachmentDescriptor colorAttachments[kMaxColorAttachments];
- wgpu::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
- };
- struct VertexStateDescriptor
- {
- VertexStateDescriptor();
- wgpu::VertexStateDescriptor desc;
- wgpu::VertexBufferLayoutDescriptor vertexBuffers[kMaxVertexInputs];
- wgpu::VertexAttributeDescriptor attributes[kMaxVertexAttributes];
- };
- struct RenderPipelineDescriptor
- {
- RenderPipelineDescriptor();
- wgpu::RenderPipelineDescriptor desc;
- //wgpu::ProgrammableStageDescriptor vertexStage;
- wgpu::ProgrammableStageDescriptor fragmentStage;
- wgpu::VertexStateDescriptor inputState;
- wgpu::RasterizationStateDescriptor rasterizationState;
- wgpu::DepthStencilStateDescriptor depthStencilState;
- wgpu::ColorStateDescriptor colorStates[kMaxColorAttachments];
- };
- struct BindingsWgpu
- {
- uint32_t numEntries = 0;
- wgpu::BindGroupEntry m_entries[2 + BGFX_CONFIG_MAX_TEXTURE_SAMPLERS*3];
- };
- struct BindStateWgpu
- {
- void clear();
- uint32_t numOffset;
- wgpu::BindGroup m_bindGroup;
- };
- struct RenderPassStateWgpu
- {
- RenderPassDescriptor m_rpd;
- };
- struct PipelineStateWgpu
- {
- RenderPipelineDescriptor m_rpd;
- wgpu::PipelineLayout m_layout;
- wgpu::RenderPipeline m_rps;
- wgpu::ComputePipeline m_cps;
- };
- void release(RenderPassStateWgpu* _ptr)
- {
- BX_DELETE(g_allocator, _ptr);
- }
- void release(PipelineStateWgpu* _ptr)
- {
- BX_DELETE(g_allocator, _ptr);
- }
- class StagingBufferWgpu
- {
- public:
- void create(uint32_t _size, bool mapped);
- void map();
- void unmap();
- void destroy();
- void mapped(void* _data, uint64_t _size);
- wgpu::Buffer m_buffer;
- void* m_data = NULL;
- uint64_t m_size = 0;
- };
- class ScratchBufferWgpu
- {
- public:
- void create(uint32_t _size); // , uint32_t _maxBindGroups);
- void destroy();
- void begin();
- uint32_t write(void* data, uint64_t _size, uint64_t _offset);
- uint32_t write(void* data, uint64_t _size);
- void submit();
- void release();
- StagingBufferWgpu* m_staging = NULL;
- wgpu::Buffer m_buffer;
- uint32_t m_offset;
- uint32_t m_size;
- uint8_t m_stagingIndex = 0;
- };
- class BindStateCacheWgpu
- {
- public:
- void create(); // , uint32_t _maxBindGroups);
- void destroy();
- void reset();
- BindStateWgpu m_bindStates[1024] = {};
- uint32_t m_currentBindState;
- //uint32_t m_maxBindStates;
- };
- struct ReadbackWgpu
- {
- void create(TextureHandle _texture) { m_texture = _texture; }
- void destroy()
- {
- m_buffer.Destroy();
- }
- void readback(void const* data, uint64_t size)
- {
- bx::memCopy(m_data, data, m_size < size ? m_size : size);
- m_buffer.Unmap();
- m_mapped = false;
- }
- TextureHandle m_texture;
- wgpu::Buffer m_buffer;
- uint32_t m_mip = 0;
- bool m_mapped = false;
- void* m_data = NULL;
- size_t m_size = 0;
- };
- struct TextureWgpu
- {
- enum Enum
- {
- Texture2D,
- Texture3D,
- TextureCube,
- };
- void create(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip);
- void destroy()
- {
- m_ptr.Destroy();
- }
- void update(
- uint8_t _side
- , uint8_t _mip
- , const Rect& _rect
- , uint16_t _z
- , uint16_t _depth
- , uint16_t _pitch
- , const Memory* _mem
- );
- TextureHandle m_handle;
- String m_label;
- wgpu::TextureView m_view;
- wgpu::TextureView getTextureMipLevel(int _mip);
- wgpu::Texture m_ptr;
- wgpu::Texture m_ptrMsaa;
- wgpu::TextureView m_ptrMips[14] = {};
- wgpu::Sampler m_sampler;
- uint64_t m_flags = 0;
- uint32_t m_width = 0;
- uint32_t m_height = 0;
- uint32_t m_depth = 0;
- uint8_t m_type;
- TextureFormat::Enum m_requestedFormat;
- TextureFormat::Enum m_textureFormat;
- uint8_t m_numMips = 0;
- uint8_t m_numLayers;
- uint32_t m_numSides;
- uint8_t m_sampleCount;
- ReadbackWgpu m_readback;
- };
- struct SamplerStateWgpu
- {
- wgpu::Sampler m_sampler;
- };
- void release(SamplerStateWgpu* _ptr)
- {
- BX_DELETE(g_allocator, _ptr);
- }
- struct FrameBufferWgpu;
- struct SwapChainWgpu
- {
- void init(wgpu::Device _device, void* _nwh, uint32_t _width, uint32_t _height);
- void resize(FrameBufferWgpu& _frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags);
- void flip();
- wgpu::TextureView current();
- #if !BX_PLATFORM_EMSCRIPTEN
- DawnSwapChainImplementation m_impl;
- #endif
- wgpu::SwapChain m_swapChain;
- wgpu::TextureView m_drawable;
- wgpu::Texture m_backBufferColorMsaa;
- wgpu::Texture m_backBufferDepth;
- wgpu::TextureFormat m_colorFormat;
- wgpu::TextureFormat m_depthFormat;
- uint32_t m_maxAnisotropy = 0;
- uint8_t m_sampleCount;
- };
- struct FrameBufferWgpu
- {
- void create(uint8_t _num, const Attachment* _attachment);
- bool create(
- uint16_t _denseIdx
- , void* _nwh
- , uint32_t _width
- , uint32_t _height
- , TextureFormat::Enum _format
- , TextureFormat::Enum _depthFormat
- );
- void postReset();
- uint16_t destroy();
- SwapChainWgpu* m_swapChain = NULL;
- void* m_nwh = NULL;
- uint32_t m_width;
- uint32_t m_height;
- uint16_t m_denseIdx = UINT16_MAX;
- uint32_t m_pixelFormatHash = 0;
- TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS - 1];
- TextureHandle m_depthHandle = { kInvalidHandle };
- Attachment m_colorAttachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS - 1];
- Attachment m_depthAttachment;
- uint8_t m_num = 0; // number of color handles
- };
- struct CommandQueueWgpu
- {
- void init(wgpu::Queue _queue);
- void shutdown();
- void beginRender();
- void beginStaging();
- void kick(bool _endFrame, bool _waitForFinish = false);
- void finish(bool _finishAll = false);
- void release(wgpu::Buffer _buffer);
- void consume();
- #if BGFX_CONFIG_MULTITHREADED
- //bx::Semaphore m_framesSemaphore;
- #endif
- wgpu::Queue m_queue;
- wgpu::CommandEncoder m_stagingEncoder;
- wgpu::CommandEncoder m_renderEncoder;
- int m_releaseWriteIndex = 0;
- int m_releaseReadIndex = 0;
- typedef stl::vector<wgpu::Buffer> ResourceArray;
- ResourceArray m_release[WEBGPU_MAX_FRAMES_IN_FLIGHT];
- };
- struct TimerQueryWgpu
- {
- TimerQueryWgpu()
- : m_control(4)
- {
- }
- void init();
- void shutdown();
- uint32_t begin(uint32_t _resultIdx);
- void end(uint32_t _idx);
- void addHandlers(wgpu::CommandBuffer& _commandBuffer);
- bool get();
- struct Result
- {
- void reset()
- {
- m_begin = 0;
- m_end = 0;
- m_pending = 0;
- }
- uint64_t m_begin;
- uint64_t m_end;
- uint32_t m_pending;
- };
- uint64_t m_begin;
- uint64_t m_end;
- uint64_t m_elapsed;
- uint64_t m_frequency;
- Result m_result[4 * 2];
- bx::RingBufferControl m_control;
- };
- struct OcclusionQueryWgpu
- {
- OcclusionQueryWgpu()
- : m_control(BX_COUNTOF(m_query))
- {
- }
- void postReset();
- void preReset();
- void begin(wgpu::RenderPassEncoder& _rce, Frame* _render, OcclusionQueryHandle _handle);
- void end(wgpu::RenderPassEncoder& _rce);
- void resolve(Frame* _render, bool _wait = false);
- void invalidate(OcclusionQueryHandle _handle);
- struct Query
- {
- OcclusionQueryHandle m_handle;
- };
- wgpu::Buffer m_buffer;
- Query m_query[BGFX_CONFIG_MAX_OCCLUSION_QUERIES];
- bx::RingBufferControl m_control;
- };
- } /* namespace webgpu */ } // namespace bgfx
- #endif // BGFX_CONFIG_RENDERER_WEBGPU
- #endif // BGFX_RENDERER_WEBGPU_H_HEADER_GUARD
|