renderer_webgpu.h 12 KB

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