renderer_webgpu.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. /*
  2. * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #ifndef BGFX_RENDERER_WEBGPU_H_HEADER_GUARD
  6. #define BGFX_RENDERER_WEBGPU_H_HEADER_GUARD
  7. #include "bgfx_p.h"
  8. #if BGFX_CONFIG_RENDERER_WEBGPU
  9. #if !BX_PLATFORM_EMSCRIPTEN
  10. # include <dawn/webgpu_cpp.h>
  11. # include <dawn/dawn_wsi.h>
  12. #else
  13. # include <webgpu/webgpu_cpp.h>
  14. #endif // !BX_PLATFORM_EMSCRIPTEN
  15. #define BGFX_WEBGPU_PROFILER_BEGIN(_view, _abgr) \
  16. BX_MACRO_BLOCK_BEGIN \
  17. BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \
  18. BX_MACRO_BLOCK_END
  19. #define BGFX_WEBGPU_PROFILER_BEGIN_LITERAL(_name, _abgr) \
  20. BX_MACRO_BLOCK_BEGIN \
  21. BGFX_PROFILER_BEGIN_LITERAL("" # _name, _abgr); \
  22. BX_MACRO_BLOCK_END
  23. #define BGFX_WEBGPU_PROFILER_END() \
  24. BX_MACRO_BLOCK_BEGIN \
  25. BGFX_PROFILER_END(); \
  26. BX_MACRO_BLOCK_END
  27. #define WEBGPU_MAX_FRAMES_IN_FLIGHT 3
  28. #define WEBGPU_NUM_UNIFORM_BUFFERS 8
  29. namespace bgfx { namespace webgpu
  30. {
  31. template <typename Ty>
  32. class StateCacheT
  33. {
  34. public:
  35. void add(uint64_t _id, Ty _item)
  36. {
  37. invalidate(_id);
  38. m_hashMap.insert(stl::make_pair(_id, _item));
  39. }
  40. Ty find(uint64_t _id)
  41. {
  42. typename HashMap::iterator it = m_hashMap.find(_id);
  43. if(it != m_hashMap.end())
  44. {
  45. return it->second;
  46. }
  47. return NULL;
  48. }
  49. void invalidate(uint64_t _id)
  50. {
  51. typename HashMap::iterator it = m_hashMap.find(_id);
  52. if(it != m_hashMap.end())
  53. {
  54. release(it->second);
  55. m_hashMap.erase(it);
  56. }
  57. }
  58. void invalidate()
  59. {
  60. for(typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
  61. {
  62. release(it->second);
  63. }
  64. m_hashMap.clear();
  65. }
  66. uint32_t getCount() const
  67. {
  68. return uint32_t(m_hashMap.size());
  69. }
  70. private:
  71. typedef stl::unordered_map<uint64_t, Ty> HashMap;
  72. HashMap m_hashMap;
  73. };
  74. struct BufferWgpu
  75. {
  76. void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false);
  77. void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
  78. void destroy()
  79. {
  80. m_ptr.Destroy();
  81. if(NULL != m_dynamic)
  82. {
  83. BX_DELETE(g_allocator, m_dynamic);
  84. m_dynamic = NULL;
  85. }
  86. }
  87. uint32_t m_size;
  88. uint16_t m_flags = BGFX_BUFFER_NONE;
  89. bool m_vertex;
  90. String m_label;
  91. wgpu::Buffer m_ptr;
  92. uint8_t* m_dynamic = NULL;
  93. };
  94. typedef BufferWgpu IndexBufferWgpu;
  95. struct VertexBufferWgpu : public BufferWgpu
  96. {
  97. void create(uint32_t _size, void* _data, VertexLayoutHandle _declHandle, uint16_t _flags);
  98. VertexLayoutHandle m_layoutHandle;
  99. };
  100. struct BindInfo
  101. {
  102. uint32_t m_index = UINT32_MAX;
  103. uint32_t m_binding = UINT32_MAX;
  104. UniformHandle m_uniform = BGFX_INVALID_HANDLE;
  105. };
  106. struct ShaderWgpu
  107. {
  108. void create(ShaderHandle _handle, const Memory* _mem);
  109. void destroy()
  110. {
  111. if (NULL != m_constantBuffer)
  112. {
  113. UniformBuffer::destroy(m_constantBuffer);
  114. m_constantBuffer = NULL;
  115. }
  116. m_module = NULL;
  117. }
  118. const char* name() const { return getName(m_handle); }
  119. ShaderHandle m_handle;
  120. String m_label;
  121. wgpu::ShaderStage m_stage;
  122. wgpu::ShaderModule m_module;
  123. uint32_t* m_code = NULL;
  124. size_t m_codeSize = 0;
  125. UniformBuffer* m_constantBuffer = NULL;
  126. PredefinedUniform m_predefined[PredefinedUniform::Count];
  127. uint16_t m_attrMask[Attrib::Count];
  128. uint8_t m_attrRemap[Attrib::Count];
  129. uint32_t m_hash = 0;
  130. uint16_t m_numUniforms = 0;
  131. uint16_t m_size = 0;
  132. uint16_t m_gpuSize = 0;
  133. uint8_t m_numPredefined = 0;
  134. uint8_t m_numAttrs = 0;
  135. BindInfo m_bindInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  136. wgpu::BindGroupLayoutEntry m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  137. wgpu::BindGroupLayoutEntry m_textures[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  138. uint8_t m_numSamplers = 0;
  139. wgpu::BindGroupLayoutEntry m_buffers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  140. uint32_t m_numBuffers = 0;
  141. };
  142. struct PipelineStateWgpu;
  143. struct ProgramWgpu
  144. {
  145. void create(const ShaderWgpu* _vsh, const ShaderWgpu* _fsh);
  146. void destroy();
  147. const ShaderWgpu* m_vsh = NULL;
  148. const ShaderWgpu* m_fsh = NULL;
  149. PredefinedUniform m_predefined[PredefinedUniform::Count * 2];
  150. uint8_t m_numPredefined;
  151. PipelineStateWgpu* m_computePS = NULL;
  152. wgpu::BindGroupLayout m_bindGroupLayout;
  153. uint16_t m_gpuSize = 0;
  154. uint32_t m_numUniforms;
  155. uint32_t m_bindGroupLayoutHash;
  156. BindInfo m_bindInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  157. wgpu::BindGroupLayoutEntry m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  158. wgpu::BindGroupLayoutEntry m_textures[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  159. uint32_t m_numSamplers = 0;
  160. wgpu::BindGroupLayoutEntry m_buffers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  161. uint32_t m_numBuffers = 0;
  162. };
  163. constexpr size_t kMaxVertexInputs = 16;
  164. constexpr size_t kMaxVertexAttributes = 16;
  165. constexpr size_t kMaxColorAttachments = BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS;
  166. constexpr uint32_t kMinBufferOffsetAlignment = 256;
  167. struct RenderPassDescriptor
  168. {
  169. RenderPassDescriptor();
  170. wgpu::RenderPassDescriptor desc;
  171. wgpu::RenderPassColorAttachmentDescriptor colorAttachments[kMaxColorAttachments];
  172. wgpu::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
  173. };
  174. struct VertexStateDescriptor
  175. {
  176. VertexStateDescriptor();
  177. wgpu::VertexStateDescriptor desc;
  178. wgpu::VertexBufferLayoutDescriptor vertexBuffers[kMaxVertexInputs];
  179. wgpu::VertexAttributeDescriptor attributes[kMaxVertexAttributes];
  180. };
  181. struct RenderPipelineDescriptor
  182. {
  183. RenderPipelineDescriptor();
  184. wgpu::RenderPipelineDescriptor desc;
  185. //wgpu::ProgrammableStageDescriptor vertexStage;
  186. wgpu::ProgrammableStageDescriptor fragmentStage;
  187. wgpu::VertexStateDescriptor inputState;
  188. wgpu::RasterizationStateDescriptor rasterizationState;
  189. wgpu::DepthStencilStateDescriptor depthStencilState;
  190. wgpu::ColorStateDescriptor colorStates[kMaxColorAttachments];
  191. };
  192. struct BindingsWgpu
  193. {
  194. uint32_t numEntries = 0;
  195. wgpu::BindGroupEntry m_entries[2 + BGFX_CONFIG_MAX_TEXTURE_SAMPLERS*3];
  196. };
  197. struct BindStateWgpu
  198. {
  199. void clear();
  200. uint32_t numOffset;
  201. wgpu::BindGroup m_bindGroup;
  202. };
  203. struct RenderPassStateWgpu
  204. {
  205. RenderPassDescriptor m_rpd;
  206. };
  207. struct PipelineStateWgpu
  208. {
  209. RenderPipelineDescriptor m_rpd;
  210. wgpu::PipelineLayout m_layout;
  211. wgpu::RenderPipeline m_rps;
  212. wgpu::ComputePipeline m_cps;
  213. };
  214. void release(RenderPassStateWgpu* _ptr)
  215. {
  216. BX_DELETE(g_allocator, _ptr);
  217. }
  218. void release(PipelineStateWgpu* _ptr)
  219. {
  220. BX_DELETE(g_allocator, _ptr);
  221. }
  222. class StagingBufferWgpu
  223. {
  224. public:
  225. void create(uint32_t _size, bool mapped);
  226. void map();
  227. void unmap();
  228. void destroy();
  229. void mapped(void* _data, uint64_t _size);
  230. wgpu::Buffer m_buffer;
  231. void* m_data = NULL;
  232. uint64_t m_size = 0;
  233. };
  234. class ScratchBufferWgpu
  235. {
  236. public:
  237. void create(uint32_t _size); // , uint32_t _maxBindGroups);
  238. void destroy();
  239. void begin();
  240. uint32_t write(void* data, uint64_t _size, uint64_t _offset);
  241. uint32_t write(void* data, uint64_t _size);
  242. void submit();
  243. void release();
  244. StagingBufferWgpu* m_staging = NULL;
  245. wgpu::Buffer m_buffer;
  246. uint32_t m_offset;
  247. uint32_t m_size;
  248. uint8_t m_stagingIndex = 0;
  249. };
  250. class BindStateCacheWgpu
  251. {
  252. public:
  253. void create(); // , uint32_t _maxBindGroups);
  254. void destroy();
  255. void reset();
  256. BindStateWgpu m_bindStates[1024] = {};
  257. uint32_t m_currentBindState;
  258. //uint32_t m_maxBindStates;
  259. };
  260. struct ReadbackWgpu
  261. {
  262. void create(TextureHandle _texture) { m_texture = _texture; }
  263. void destroy()
  264. {
  265. m_buffer.Destroy();
  266. }
  267. void readback(void const* data, uint64_t size)
  268. {
  269. bx::memCopy(m_data, data, m_size < size ? m_size : size);
  270. m_buffer.Unmap();
  271. m_mapped = false;
  272. }
  273. TextureHandle m_texture;
  274. wgpu::Buffer m_buffer;
  275. uint32_t m_mip = 0;
  276. bool m_mapped = false;
  277. void* m_data = NULL;
  278. size_t m_size = 0;
  279. };
  280. struct TextureWgpu
  281. {
  282. enum Enum
  283. {
  284. Texture2D,
  285. Texture3D,
  286. TextureCube,
  287. };
  288. void create(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip);
  289. void destroy()
  290. {
  291. m_ptr.Destroy();
  292. }
  293. void update(
  294. uint8_t _side
  295. , uint8_t _mip
  296. , const Rect& _rect
  297. , uint16_t _z
  298. , uint16_t _depth
  299. , uint16_t _pitch
  300. , const Memory* _mem
  301. );
  302. TextureHandle m_handle;
  303. String m_label;
  304. wgpu::TextureView m_view;
  305. wgpu::TextureView getTextureMipLevel(int _mip);
  306. wgpu::Texture m_ptr;
  307. wgpu::Texture m_ptrMsaa;
  308. wgpu::TextureView m_ptrMips[14] = {};
  309. wgpu::Sampler m_sampler;
  310. uint64_t m_flags = 0;
  311. uint32_t m_width = 0;
  312. uint32_t m_height = 0;
  313. uint32_t m_depth = 0;
  314. uint8_t m_type;
  315. TextureFormat::Enum m_requestedFormat;
  316. TextureFormat::Enum m_textureFormat;
  317. uint8_t m_numMips = 0;
  318. uint8_t m_numLayers;
  319. uint32_t m_numSides;
  320. uint8_t m_sampleCount;
  321. ReadbackWgpu m_readback;
  322. };
  323. struct SamplerStateWgpu
  324. {
  325. wgpu::Sampler m_sampler;
  326. };
  327. void release(SamplerStateWgpu* _ptr)
  328. {
  329. BX_DELETE(g_allocator, _ptr);
  330. }
  331. struct FrameBufferWgpu;
  332. struct SwapChainWgpu
  333. {
  334. void init(wgpu::Device _device, void* _nwh, uint32_t _width, uint32_t _height);
  335. void resize(FrameBufferWgpu& _frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags);
  336. void flip();
  337. wgpu::TextureView current();
  338. #if !BX_PLATFORM_EMSCRIPTEN
  339. DawnSwapChainImplementation m_impl;
  340. #endif
  341. wgpu::SwapChain m_swapChain;
  342. wgpu::TextureView m_drawable;
  343. wgpu::Texture m_backBufferColorMsaa;
  344. wgpu::Texture m_backBufferDepth;
  345. wgpu::TextureFormat m_colorFormat;
  346. wgpu::TextureFormat m_depthFormat;
  347. uint32_t m_maxAnisotropy = 0;
  348. uint8_t m_sampleCount;
  349. };
  350. struct FrameBufferWgpu
  351. {
  352. void create(uint8_t _num, const Attachment* _attachment);
  353. bool create(
  354. uint16_t _denseIdx
  355. , void* _nwh
  356. , uint32_t _width
  357. , uint32_t _height
  358. , TextureFormat::Enum _format
  359. , TextureFormat::Enum _depthFormat
  360. );
  361. void postReset();
  362. uint16_t destroy();
  363. SwapChainWgpu* m_swapChain = NULL;
  364. void* m_nwh = NULL;
  365. uint32_t m_width;
  366. uint32_t m_height;
  367. uint16_t m_denseIdx = UINT16_MAX;
  368. uint32_t m_pixelFormatHash = 0;
  369. TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS - 1];
  370. TextureHandle m_depthHandle = { kInvalidHandle };
  371. Attachment m_colorAttachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS - 1];
  372. Attachment m_depthAttachment;
  373. uint8_t m_num = 0; // number of color handles
  374. };
  375. struct CommandQueueWgpu
  376. {
  377. void init(wgpu::Queue _queue);
  378. void shutdown();
  379. void beginRender();
  380. void beginStaging();
  381. void kick(bool _endFrame, bool _waitForFinish = false);
  382. void finish(bool _finishAll = false);
  383. void release(wgpu::Buffer _buffer);
  384. void consume();
  385. #if BGFX_CONFIG_MULTITHREADED
  386. //bx::Semaphore m_framesSemaphore;
  387. #endif
  388. wgpu::Queue m_queue;
  389. wgpu::CommandEncoder m_stagingEncoder;
  390. wgpu::CommandEncoder m_renderEncoder;
  391. int m_releaseWriteIndex = 0;
  392. int m_releaseReadIndex = 0;
  393. typedef stl::vector<wgpu::Buffer> ResourceArray;
  394. ResourceArray m_release[WEBGPU_MAX_FRAMES_IN_FLIGHT];
  395. };
  396. struct TimerQueryWgpu
  397. {
  398. TimerQueryWgpu()
  399. : m_control(4)
  400. {
  401. }
  402. void init();
  403. void shutdown();
  404. uint32_t begin(uint32_t _resultIdx);
  405. void end(uint32_t _idx);
  406. void addHandlers(wgpu::CommandBuffer& _commandBuffer);
  407. bool get();
  408. struct Result
  409. {
  410. void reset()
  411. {
  412. m_begin = 0;
  413. m_end = 0;
  414. m_pending = 0;
  415. }
  416. uint64_t m_begin;
  417. uint64_t m_end;
  418. uint32_t m_pending;
  419. };
  420. uint64_t m_begin;
  421. uint64_t m_end;
  422. uint64_t m_elapsed;
  423. uint64_t m_frequency;
  424. Result m_result[4 * 2];
  425. bx::RingBufferControl m_control;
  426. };
  427. struct OcclusionQueryWgpu
  428. {
  429. OcclusionQueryWgpu()
  430. : m_control(BX_COUNTOF(m_query))
  431. {
  432. }
  433. void postReset();
  434. void preReset();
  435. void begin(wgpu::RenderPassEncoder& _rce, Frame* _render, OcclusionQueryHandle _handle);
  436. void end(wgpu::RenderPassEncoder& _rce);
  437. void resolve(Frame* _render, bool _wait = false);
  438. void invalidate(OcclusionQueryHandle _handle);
  439. struct Query
  440. {
  441. OcclusionQueryHandle m_handle;
  442. };
  443. wgpu::Buffer m_buffer;
  444. Query m_query[BGFX_CONFIG_MAX_OCCLUSION_QUERIES];
  445. bx::RingBufferControl m_control;
  446. };
  447. } /* namespace webgpu */ } // namespace bgfx
  448. #endif // BGFX_CONFIG_RENDERER_WEBGPU
  449. #endif // BGFX_RENDERER_WEBGPU_H_HEADER_GUARD