summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/renderer_webgpu.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/renderer_webgpu.h')
-rw-r--r--3rdparty/bgfx/src/renderer_webgpu.h570
1 files changed, 570 insertions, 0 deletions
diff --git a/3rdparty/bgfx/src/renderer_webgpu.h b/3rdparty/bgfx/src/renderer_webgpu.h
new file mode 100644
index 00000000000..54c8aff237e
--- /dev/null
+++ b/3rdparty/bgfx/src/renderer_webgpu.h
@@ -0,0 +1,570 @@
+/*
+ * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
+ */
+
+#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_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;
+ };
+
+ struct IndexBufferWgpu : public BufferWgpu
+ {
+ void create(uint32_t _size, void* _data, uint16_t _flags);
+
+ wgpu::IndexFormat m_format;
+ };
+
+ 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::RenderPassColorAttachment colorAttachments[kMaxColorAttachments];
+ wgpu::RenderPassDepthStencilAttachment depthStencilAttachment;
+ };
+
+ struct VertexStateDescriptor
+ {
+ VertexStateDescriptor();
+
+ wgpu::VertexState desc;
+
+ wgpu::VertexBufferLayoutDescriptor buffers[kMaxVertexInputs];
+ wgpu::VertexAttributeDescriptor attributes[kMaxVertexAttributes];
+ };
+
+ struct RenderPipelineDescriptor
+ {
+ RenderPipelineDescriptor();
+
+ wgpu::RenderPipelineDescriptor2 desc;
+
+ wgpu::FragmentState fragment;
+ wgpu::DepthStencilState depthStencil;
+
+ wgpu::ColorTargetState targets[kMaxColorAttachments];
+ wgpu::BlendState blends[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);
+
+ 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)
+ {
+ bx::memCopy(m_data, data, m_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[BGFX_CONFIG_MAX_FRAME_LATENCY];
+ };
+
+ struct TimerQueryWgpu
+ {
+ TimerQueryWgpu()
+ : m_control(4)
+ {
+ }
+
+ void init();
+ void shutdown();
+ uint32_t begin(uint32_t _resultIdx, uint32_t _frameNum);
+ 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;
+ m_frameNum = 0;
+ }
+
+ uint64_t m_begin;
+ uint64_t m_end;
+ uint32_t m_pending;
+ uint32_t m_frameNum; // TODO: implement (currently stays 0)
+ };
+
+ 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