Răsfoiți Sursa

Encoder API WIP.

Branimir Karadžić 8 ani în urmă
părinte
comite
0b20e92797
7 a modificat fișierele cu 1229 adăugiri și 185 ștergeri
  1. 680 10
      include/bgfx/bgfx.h
  2. 7 6
      include/bgfx/c99/bgfx.h
  3. 6 6
      include/bgfx/c99/platform.h
  4. 1 1
      include/bgfx/defines.h
  5. 356 116
      src/bgfx.cpp
  6. 175 46
      src/bgfx_p.h
  7. 4 0
      src/config.h

+ 680 - 10
include/bgfx/bgfx.h

@@ -628,6 +628,7 @@ namespace bgfx
 			uint32_t maxDynamicVertexBuffers; //!< Maximum number of dynamic vertex buffer handles.
 			uint32_t maxUniforms;             //!< Maximum number of uniform handles.
 			uint32_t maxOcclusionQueries;     //!< Maximum number of occlusion query handles.
+			uint32_t maxEncoders;             //!< Maximum number of encoder threads.
 		};
 
 		Limits limits;
@@ -820,6 +821,671 @@ namespace bgfx
 		ViewStats viewStats[256]; //!< View stats.
 	};
 
+	/// Encoder for submitting draw calls from multiple threads. Use `bgfx::begin()`
+	/// to obtain encoder for thread.
+	///
+	/// @attention C99 equivalent is `bgfx_encoder_t`.
+	///
+	struct Encoder
+	{
+		/// Sets debug marker.
+		///
+		/// @attention C99 equivalent is `bgfx_set_marker`.
+		///
+		void setMarker(const char* _marker);
+
+		/// Set render states for draw primitive.
+		///
+		/// @param[in] _state State flags. Default state for primitive type is
+		///   triangles. See: `BGFX_STATE_DEFAULT`.
+		///   - `BGFX_STATE_ALPHA_WRITE` - Enable alpha write.
+		///   - `BGFX_STATE_DEPTH_WRITE` - Enable depth write.
+		///   - `BGFX_STATE_DEPTH_TEST_*` - Depth test function.
+		///   - `BGFX_STATE_BLEND_*` - See remark 1 about BGFX_STATE_BLEND_FUNC.
+		///   - `BGFX_STATE_BLEND_EQUATION_*` - See remark 2.
+		///   - `BGFX_STATE_CULL_*` - Backface culling mode.
+		///   - `BGFX_STATE_RGB_WRITE` - Enable RGB write.
+		///   - `BGFX_STATE_MSAA` - Enable MSAA.
+		///   - `BGFX_STATE_PT_[TRISTRIP/LINES/POINTS]` - Primitive type.
+		///
+		/// @param[in] _rgba Sets blend factor used by `BGFX_STATE_BLEND_FACTOR` and
+		///   `BGFX_STATE_BLEND_INV_FACTOR` blend modes.
+		///
+		/// @remarks
+		///   1. To setup more complex states use:
+		///      `BGFX_STATE_ALPHA_REF(_ref)`,
+		///      `BGFX_STATE_POINT_SIZE(_size)`,
+		///      `BGFX_STATE_BLEND_FUNC(_src, _dst)`,
+		///      `BGFX_STATE_BLEND_FUNC_SEPARATE(_srcRGB, _dstRGB, _srcA, _dstA)`
+		///      `BGFX_STATE_BLEND_EQUATION(_equation)`
+		///      `BGFX_STATE_BLEND_EQUATION_SEPARATE(_equationRGB, _equationA)`
+		///   2. `BGFX_STATE_BLEND_EQUATION_ADD` is set when no other blend
+		///      equation is specified.
+		///
+		/// @attention C99 equivalent is `bgfx_set_state`.
+		///
+		void setState(
+			uint64_t _state
+			, uint32_t _rgba = 0
+			);
+
+		/// Set condition for rendering.
+		///
+		/// @param[in] _handle Occlusion query handle.
+		/// @param[in] _visible Render if occlusion query is visible.
+		///
+		/// @attention C99 equivalent is `bgfx_set_condition`.
+		///
+		void setCondition(
+			OcclusionQueryHandle _handle
+			, bool _visible
+			);
+
+		/// Set stencil test state.
+		///
+		/// @param[in] _fstencil Front stencil state.
+		/// @param[in] _bstencil Back stencil state. If back is set to `BGFX_STENCIL_NONE`
+		///   _fstencil is applied to both front and back facing primitives.
+		///
+		/// @attention C99 equivalent is `bgfx_set_stencil`.
+		///
+		void setStencil(
+			uint32_t _fstencil
+			, uint32_t _bstencil = BGFX_STENCIL_NONE
+			);
+
+		/// Set scissor for draw primitive. For scissor for all primitives in
+		/// view see `bgfx::setViewScissor`.
+		///
+		/// @param[in] _x Position x from the left corner of the window.
+		/// @param[in] _y Position y from the top corner of the window.
+		/// @param[in] _width Width of scissor region.
+		/// @param[in] _height Height of scissor region.
+		/// @returns Scissor cache index.
+		///
+		/// @attention C99 equivalent is `bgfx_set_scissor`.
+		///
+		uint16_t setScissor(
+			uint16_t _x
+			, uint16_t _y
+			, uint16_t _width
+			, uint16_t _height
+			);
+
+		/// Set scissor from cache for draw primitive.
+		///
+		/// @param[in] _cache Index in scissor cache. Passing UINT16_MAX unset primitive
+		///   scissor and primitive will use view scissor instead.
+		///
+		/// @attention C99 equivalent is `bgfx_set_scissor_cached`.
+		///
+		void setScissor(uint16_t _cache = UINT16_MAX);
+
+		/// Set model matrix for draw primitive. If it is not called model will
+		/// be rendered with identity model matrix.
+		///
+		/// @param[in] _mtx Pointer to first matrix in array.
+		/// @param[in] _num Number of matrices in array.
+		/// @returns index into matrix cache in case the same model matrix has
+		///   to be used for other draw primitive call.
+		///
+		/// @attention C99 equivalent is `bgfx_set_transform`.
+		///
+		uint32_t setTransform(
+			const void* _mtx
+			, uint16_t _num = 1
+			);
+
+		/// Reserve `_num` matrices in internal matrix cache.
+		///
+		/// @param[in] _transform Pointer to `Transform` structure.
+		/// @param[in] _num Number of matrices.
+		/// @returns index into matrix cache.
+		///
+		/// @attention Pointer returned can be modifed until `bgfx::frame` is called.
+		/// @attention C99 equivalent is `bgfx_alloc_transform`.
+		///
+		uint32_t allocTransform(
+			Transform* _transform
+			, uint16_t _num
+			);
+
+		/// Set model matrix from matrix cache for draw primitive.
+		///
+		/// @param[in] _cache Index in matrix cache.
+		/// @param[in] _num Number of matrices from cache.
+		///
+		/// @attention C99 equivalent is `bgfx_set_transform_cached`.
+		///
+		void setTransform(
+			uint32_t _cache
+			, uint16_t _num = 1
+			);
+
+		/// Set shader uniform parameter for draw primitive.
+		///
+		/// @param[in] _handle Uniform.
+		/// @param[in] _value Pointer to uniform data.
+		/// @param[in] _num Number of elements. Passing `UINT16_MAX` will
+		///   use the _num passed on uniform creation.
+		///
+		/// @attention C99 equivalent is `bgfx_set_uniform`.
+		///
+		void setUniform(
+			UniformHandle _handle
+			, const void* _value
+			, uint16_t _num = 1
+			);
+
+		/// Set index buffer for draw primitive.
+		///
+		/// @param[in] _handle Index buffer.
+		///
+		/// @attention C99 equivalent is `bgfx_set_index_buffer`.
+		///
+		void setIndexBuffer(IndexBufferHandle _handle);
+
+		/// Set index buffer for draw primitive.
+		///
+		/// @param[in] _handle Index buffer.
+		/// @param[in] _firstIndex First index to render.
+		/// @param[in] _numIndices Number of indices to render.
+		///
+		/// @attention C99 equivalent is `bgfx_set_index_buffer`.
+		///
+		void setIndexBuffer(
+			IndexBufferHandle _handle
+			, uint32_t _firstIndex
+			, uint32_t _numIndices
+			);
+
+		/// Set index buffer for draw primitive.
+		///
+		/// @param[in] _handle Dynamic index buffer.
+		///
+		/// @attention C99 equivalent is `bgfx_set_dynamic_index_buffer`.
+		///
+		void setIndexBuffer(DynamicIndexBufferHandle _handle);
+
+		/// Set index buffer for draw primitive.
+		///
+		/// @param[in] _handle Dynamic index buffer.
+		/// @param[in] _firstIndex First index to render.
+		/// @param[in] _numIndices Number of indices to render.
+		///
+		/// @attention C99 equivalent is `bgfx_set_dynamic_index_buffer`.
+		///
+		void setIndexBuffer(
+			DynamicIndexBufferHandle _handle
+			, uint32_t _firstIndex
+			, uint32_t _numIndices
+			);
+
+		/// Set index buffer for draw primitive.
+		///
+		/// @param[in] _tib Transient index buffer.
+		///
+		/// @remarks
+		///   _tib pointer after this call is invalid.
+		///
+		/// @attention C99 equivalent is `bgfx_set_transient_index_buffer`.
+		///
+		void setIndexBuffer(const TransientIndexBuffer* _tib);
+
+		/// Set index buffer for draw primitive.
+		///
+		/// @param[in] _tib Transient index buffer.
+		/// @param[in] _firstIndex First index to render.
+		/// @param[in] _numIndices Number of indices to render.
+		///
+		/// @remarks
+		///   _tib pointer after this call is invalid.
+		///
+		/// @attention C99 equivalent is `bgfx_set_transient_index_buffer`.
+		///
+		void setIndexBuffer(
+			const TransientIndexBuffer* _tib
+			, uint32_t _firstIndex
+			, uint32_t _numIndices
+			);
+
+		/// Set vertex buffer for draw primitive.
+		///
+		/// @param[in] _stream Vertex stream.
+		/// @param[in] _handle Vertex buffer.
+		///
+		/// @attention C99 equivalent is `bgfx_set_vertex_buffer`.
+		///
+		void setVertexBuffer(
+			uint8_t _stream
+			, VertexBufferHandle _handle
+			);
+
+		/// Set vertex buffer for draw primitive.
+		///
+		/// @param[in] _stream Vertex stream.
+		/// @param[in] _handle Vertex buffer.
+		/// @param[in] _startVertex First vertex to render.
+		/// @param[in] _numVertices Number of vertices to render.
+		///
+		/// @attention C99 equivalent is `bgfx_set_vertex_buffer`.
+		///
+		void setVertexBuffer(
+			uint8_t _stream
+			, VertexBufferHandle _handle
+			, uint32_t _startVertex
+			, uint32_t _numVertices
+			);
+
+		/// Set vertex buffer for draw primitive.
+		///
+		/// @param[in] _stream Vertex stream.
+		/// @param[in] _handle Dynamic vertex buffer.
+		///
+		/// @attention C99 equivalent is `bgfx_set_dynamic_vertex_buffer`.
+		///
+		void setVertexBuffer(
+			uint8_t _stream
+			, DynamicVertexBufferHandle _handle
+			);
+
+		/// Set vertex buffer for draw primitive.
+		///
+		/// @param[in] _stream Vertex stream.
+		/// @param[in] _handle Dynamic vertex buffer.
+		/// @param[in] _startVertex First vertex to render.
+		/// @param[in] _numVertices Number of vertices to render.
+		///
+		/// @attention C99 equivalent is `bgfx_set_dynamic_vertex_buffer`.
+		///
+		void setVertexBuffer(
+			uint8_t _stream
+			, DynamicVertexBufferHandle _handle
+			, uint32_t _startVertex
+			, uint32_t _numVertices
+			);
+
+		/// Set vertex buffer for draw primitive.
+		///
+		/// @param[in] _stream Vertex stream.
+		/// @param[in] _tvb Transient vertex buffer.
+		///
+		/// @remarks
+		///   _tvb pointer after this call is invalid.
+		///
+		/// @attention C99 equivalent is `bgfx_set_transient_vertex_buffer`.
+		///
+		void setVertexBuffer(
+			uint8_t _stream
+			, const TransientVertexBuffer* _tvb
+			);
+
+		/// Set vertex buffer for draw primitive.
+		///
+		/// @param[in] _stream Vertex stream.
+		/// @param[in] _tvb Transient vertex buffer.
+		/// @param[in] _startVertex First vertex to render.
+		/// @param[in] _numVertices Number of vertices to render.
+		///
+		/// @remarks
+		///   _tvb pointer after this call is invalid.
+		///
+		/// @attention C99 equivalent is `bgfx_set_transient_vertex_buffer`.
+		///
+		void setVertexBuffer(
+			uint8_t _stream
+			, const TransientVertexBuffer* _tvb
+			, uint32_t _startVertex
+			, uint32_t _numVertices
+			);
+
+		/// Set instance data buffer for draw primitive.
+		///
+		/// @param[in] _idb Transient instance data buffer.
+		/// @param[in] _num Number of data instances.
+		///
+		/// @remarks
+		///   _idb pointer after this call is invalid.
+		///
+		/// @attention C99 equivalent is `bgfx_set_instance_data_buffer`.
+		///
+		void setInstanceDataBuffer(
+			const InstanceDataBuffer* _idb
+			, uint32_t _num = UINT32_MAX
+			);
+
+		/// Set instance data buffer for draw primitive.
+		///
+		/// @param[in] _handle Vertex buffer.
+		/// @param[in] _start First instance data.
+		/// @param[in] _num Number of data instances.
+		///
+		/// @attention C99 equivalent is `bgfx_set_instance_data_from_vertex_buffer`.
+		///
+		void setInstanceDataBuffer(
+			VertexBufferHandle _handle
+			, uint32_t _start
+			, uint32_t _num
+			);
+
+		/// Set instance data buffer for draw primitive.
+		///
+		/// @param[in] _handle Vertex buffer.
+		/// @param[in] _start First instance data.
+		/// @param[in] _num Number of data instances.
+		///
+		/// @attention C99 equivalent is `bgfx_set_instance_data_from_dynamic_vertex_buffer`.
+		///
+		void setInstanceDataBuffer(
+			DynamicVertexBufferHandle _handle
+			, uint32_t _start
+			, uint32_t _num
+			);
+
+		/// Set texture stage for draw primitive.
+		///
+		/// @param[in] _stage Texture unit.
+		/// @param[in] _sampler Program sampler.
+		/// @param[in] _handle Texture handle.
+		/// @param[in] _flags Texture sampling mode. Default value UINT32_MAX uses
+		///   texture sampling settings from the texture.
+		///   - `BGFX_TEXTURE_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap
+		///     mode.
+		///   - `BGFX_TEXTURE_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic
+		///     sampling.
+		///
+		/// @attention C99 equivalent is `bgfx_set_texture`.
+		///
+		void setTexture(
+			uint8_t _stage
+			, UniformHandle _sampler
+			, TextureHandle _handle
+			, uint32_t _flags = UINT32_MAX
+			);
+
+		/// Submit an empty primitive for rendering. Uniforms and draw state
+		/// will be applied but no geometry will be submitted.
+		///
+		/// These empty draw calls will sort before ordinary draw calls.
+		///
+		/// @param[in] _id View id.
+		///
+		void touch(uint8_t _id);
+
+		/// Submit primitive for rendering.
+		///
+		/// @param[in] _id View id.
+		/// @param[in] _program Program.
+		/// @param[in] _depth Depth for sorting.
+		/// @param[in] _preserveState Preserve internal draw state for next draw
+		///   call submit.
+		///
+		/// @attention C99 equivalent is `bgfx_submit`.
+		///
+		void submit(
+			uint8_t _id
+			, ProgramHandle _program
+			, int32_t _depth = 0
+			, bool _preserveState = false
+			);
+
+		/// Submit primitive with occlusion query for rendering.
+		///
+		/// @param[in] _id View id.
+		/// @param[in] _program Program.
+		/// @param[in] _occlusionQuery Occlusion query.
+		/// @param[in] _depth Depth for sorting.
+		/// @param[in] _preserveState Preserve internal draw state for next draw
+		///   call submit.
+		///
+		/// @attention C99 equivalent is `bgfx_submit_occlusion_query`.
+		///
+		void submit(
+			uint8_t _id
+			, ProgramHandle _program
+			, OcclusionQueryHandle _occlusionQuery
+			, int32_t _depth = 0
+			, bool _preserveState = false
+			);
+
+		/// Submit primitive for rendering with index and instance data info from
+		/// indirect buffer.
+		///
+		/// @param[in] _id View id.
+		/// @param[in] _program Program.
+		/// @param[in] _indirectHandle Indirect buffer.
+		/// @param[in] _start First element in indirect buffer.
+		/// @param[in] _num Number of dispatches.
+		/// @param[in] _depth Depth for sorting.
+		/// @param[in] _preserveState Preserve internal draw state for next draw
+		///   call submit.
+		///
+		/// @attention C99 equivalent is `bgfx_submit_indirect`.
+		///
+		void submit(
+			uint8_t _id
+			, ProgramHandle _program
+			, IndirectBufferHandle _indirectHandle
+			, uint16_t _start = 0
+			, uint16_t _num = 1
+			, int32_t _depth = 0
+			, bool _preserveState = false
+			);
+
+		/// Set compute index buffer.
+		///
+		/// @param[in] _stage Compute stage.
+		/// @param[in] _handle Index buffer handle.
+		/// @param[in] _access Buffer access. See `Access::Enum`.
+		///
+		/// @attention C99 equivalent is `bgfx_set_compute_index_buffer`.
+		///
+		void setBuffer(
+			uint8_t _stage
+			, IndexBufferHandle _handle
+			, Access::Enum _access
+			);
+
+		/// Set compute vertex buffer.
+		///
+		/// @param[in] _stage Compute stage.
+		/// @param[in] _handle Vertex buffer handle.
+		/// @param[in] _access Buffer access. See `Access::Enum`.
+		///
+		/// @attention C99 equivalent is `bgfx_set_compute_vertex_buffer`.
+		///
+		void setBuffer(
+			uint8_t _stage
+			, VertexBufferHandle _handle
+			, Access::Enum _access
+			);
+
+		/// Set compute dynamic index buffer.
+		///
+		/// @param[in] _stage Compute stage.
+		/// @param[in] _handle Dynamic index buffer handle.
+		/// @param[in] _access Buffer access. See `Access::Enum`.
+		///
+		/// @attention C99 equivalent is `bgfx_set_compute_dynamic_index_buffer`.
+		///
+		void setBuffer(
+			uint8_t _stage
+			, DynamicIndexBufferHandle _handle
+			, Access::Enum _access
+			);
+
+		/// Set compute dynamic vertex buffer.
+		///
+		/// @param[in] _stage Compute stage.
+		/// @param[in] _handle Dynamic vertex buffer handle.
+		/// @param[in] _access Buffer access. See `Access::Enum`.
+		///
+		/// @attention C99 equivalent is `bgfx_set_compute_dynamic_vertex_buffer`.
+		///
+		void setBuffer(
+			uint8_t _stage
+			, DynamicVertexBufferHandle _handle
+			, Access::Enum _access
+			);
+
+		/// Set compute indirect buffer.
+		///
+		/// @param[in] _stage Compute stage.
+		/// @param[in] _handle Indirect buffer handle.
+		/// @param[in] _access Buffer access. See `Access::Enum`.
+		///
+		/// @attention C99 equivalent is `bgfx_set_compute_indirect_buffer`.
+		///
+		void setBuffer(
+			uint8_t _stage
+			, IndirectBufferHandle _handle
+			, Access::Enum _access
+			);
+
+		/// Set compute image from texture.
+		///
+		/// @param[in] _stage Texture unit.
+		/// @param[in] _sampler Program sampler.
+		/// @param[in] _handle Texture handle.
+		/// @param[in] _mip Mip level.
+		/// @param[in] _access Texture access. See `Access::Enum`.
+		/// @param[in] _format Texture format. See: `TextureFormat::Enum`.
+		///
+		/// @attention C99 equivalent is `bgfx_set_image`.
+		///
+		void setImage(
+			uint8_t _stage
+			, UniformHandle _sampler
+			, TextureHandle _handle
+			, uint8_t _mip
+			, Access::Enum _access
+			, TextureFormat::Enum _format = TextureFormat::Count
+			);
+
+		/// Dispatch compute.
+		///
+		/// @param[in] _id View id.
+		/// @param[in] _handle Compute program.
+		/// @param[in] _numX Number of groups X.
+		/// @param[in] _numY Number of groups Y.
+		/// @param[in] _numZ Number of groups Z.
+		/// @param[in] _flags View flags. Use
+		///   - `BGFX_VIEW_NONE` - View will be rendered only once if stereo mode is enabled.
+		///   - `BGFX_VIEW_STEREO` - View will be rendered for both eyes if stereo mode is enabled. When
+		///     stereo mode is disabled this flag doesn't have effect.
+		///
+		/// @attention C99 equivalent is `bgfx_dispatch`.
+		///
+		void dispatch(
+			uint8_t _id
+			, ProgramHandle _handle
+			, uint32_t _numX = 1
+			, uint32_t _numY = 1
+			, uint32_t _numZ = 1
+			, uint8_t _flags = BGFX_SUBMIT_EYE_FIRST
+			);
+
+		/// Dispatch compute indirect.
+		///
+		/// @param[in] _id View id.
+		/// @param[in] _handle Compute program.
+		/// @param[in] _indirectHandle Indirect buffer.
+		/// @param[in] _start First element in indirect buffer.
+		/// @param[in] _num Number of dispatches.
+		/// @param[in] _flags View flags. Use
+		///   - `BGFX_VIEW_NONE` - View will be rendered only once if stereo mode is enabled.
+		///   - `BGFX_VIEW_STEREO` - View will be rendered for both eyes if stereo mode is enabled. When
+		///     stereo mode is disabled this flag doesn't have effect.
+		///
+		/// @attention C99 equivalent is `bgfx_dispatch_indirect`.
+		///
+		void dispatch(
+			uint8_t _id
+			, ProgramHandle _handle
+			, IndirectBufferHandle _indirectHandle
+			, uint16_t _start = 0
+			, uint16_t _num = 1
+			, uint8_t _flags = BGFX_SUBMIT_EYE_FIRST
+			);
+
+		/// Discard all previously set state for draw or compute call.
+		///
+		/// @attention C99 equivalent is `bgfx_discard`.
+		///
+		void discard();
+
+		/// Blit texture 2D region between two 2D textures.
+		///
+		/// @param[in] _id View id.
+		/// @param[in] _dst Destination texture handle.
+		/// @param[in] _dstX Destination texture X position.
+		/// @param[in] _dstY Destination texture Y position.
+		/// @param[in] _src Source texture handle.
+		/// @param[in] _srcX Source texture X position.
+		/// @param[in] _srcY Source texture Y position.
+		/// @param[in] _width Width of region.
+		/// @param[in] _height Height of region.
+		///
+		/// @attention Destination texture must be create with `BGFX_TEXTURE_BLIT_DST` flag.
+		/// @attention Availability depends on: `BGFX_CAPS_TEXTURE_BLIT`.
+		/// @attention C99 equivalent is `bgfx_blit`.
+		///
+		void blit(
+			uint8_t _id
+			, TextureHandle _dst
+			, uint16_t _dstX
+			, uint16_t _dstY
+			, TextureHandle _src
+			, uint16_t _srcX = 0
+			, uint16_t _srcY = 0
+			, uint16_t _width = UINT16_MAX
+			, uint16_t _height = UINT16_MAX
+			);
+
+		/// Blit texture region between two textures.
+		///
+		/// @param[in] _id View id.
+		/// @param[in] _dst Destination texture handle.
+		/// @param[in] _dstMip Destination texture mip level.
+		/// @param[in] _dstX Destination texture X position.
+		/// @param[in] _dstY Destination texture Y position.
+		/// @param[in] _dstZ If texture is 2D this argument should be 0. If destination texture is cube
+		///   this argument represent destination texture cube face. For 3D texture this argument
+		///   represent destination texture Z position.
+		/// @param[in] _src Source texture handle.
+		/// @param[in] _srcMip Source texture mip level.
+		/// @param[in] _srcX Source texture X position.
+		/// @param[in] _srcY Source texture Y position.
+		/// @param[in] _srcZ If texture is 2D this argument should be 0. If source texture is cube
+		///   this argument represent source texture cube face. For 3D texture this argument
+		///   represent source texture Z position.
+		/// @param[in] _width Width of region.
+		/// @param[in] _height Height of region.
+		/// @param[in] _depth If texture is 3D this argument represent depth of region, otherwise is
+		///   unused.
+		///
+		/// @attention Destination texture must be create with `BGFX_TEXTURE_BLIT_DST` flag.
+		/// @attention Availability depends on: `BGFX_CAPS_TEXTURE_BLIT`.
+		/// @attention C99 equivalent is `bgfx_blit`.
+		///
+		void blit(
+			uint8_t _id
+			, TextureHandle _dst
+			, uint8_t _dstMip
+			, uint16_t _dstX
+			, uint16_t _dstY
+			, uint16_t _dstZ
+			, TextureHandle _src
+			, uint8_t _srcMip = 0
+			, uint16_t _srcX = 0
+			, uint16_t _srcY = 0
+			, uint16_t _srcZ = 0
+			, uint16_t _width = UINT16_MAX
+			, uint16_t _height = UINT16_MAX
+			, uint16_t _depth = UINT16_MAX
+			);
+	};
+
 	/// Vertex declaration.
 	///
 	/// @attention C99 equivalent is `bgfx_vertex_decl_t`.
@@ -1128,6 +1794,14 @@ namespace bgfx
 		, uint32_t _flags = BGFX_RESET_NONE
 		);
 
+	/// Begin submitting draw calls from thread.
+	///
+	Encoder* begin();
+
+	/// End submitting draw calls from thread.
+	///
+	void end(Encoder* _encoder);
+
 	/// Advance to next frame. When using multithreaded renderer, this call
 	/// just swaps internal buffers, kicks render thread, and returns. In
 	/// singlethreaded renderer this call does frame rendering.
@@ -2855,9 +3529,8 @@ namespace bgfx
 	/// These empty draw calls will sort before ordinary draw calls.
 	///
 	/// @param[in] _id View id.
-	/// @returns Number of draw calls.
 	///
-	uint32_t touch(uint8_t _id);
+	void touch(uint8_t _id);
 
 	/// Submit primitive for rendering.
 	///
@@ -2866,11 +3539,10 @@ namespace bgfx
 	/// @param[in] _depth Depth for sorting.
 	/// @param[in] _preserveState Preserve internal draw state for next draw
 	///   call submit.
-	/// @returns Number of draw calls.
 	///
 	/// @attention C99 equivalent is `bgfx_submit`.
 	///
-	uint32_t submit(
+	void submit(
 		  uint8_t _id
 		, ProgramHandle _program
 		, int32_t _depth = 0
@@ -2885,11 +3557,10 @@ namespace bgfx
 	/// @param[in] _depth Depth for sorting.
 	/// @param[in] _preserveState Preserve internal draw state for next draw
 	///   call submit.
-	/// @returns Number of draw calls.
 	///
 	/// @attention C99 equivalent is `bgfx_submit_occlusion_query`.
 	///
-	uint32_t submit(
+	void submit(
 		  uint8_t _id
 		, ProgramHandle _program
 		, OcclusionQueryHandle _occlusionQuery
@@ -2908,11 +3579,10 @@ namespace bgfx
 	/// @param[in] _depth Depth for sorting.
 	/// @param[in] _preserveState Preserve internal draw state for next draw
 	///   call submit.
-	/// @returns Number of draw calls.
 	///
 	/// @attention C99 equivalent is `bgfx_submit_indirect`.
 	///
-	uint32_t submit(
+	void submit(
 		  uint8_t _id
 		, ProgramHandle _program
 		, IndirectBufferHandle _indirectHandle
@@ -3026,7 +3696,7 @@ namespace bgfx
 	///
 	/// @attention C99 equivalent is `bgfx_dispatch`.
 	///
-	uint32_t dispatch(
+	void dispatch(
 		  uint8_t _id
 		, ProgramHandle _handle
 		, uint32_t _numX = 1
@@ -3049,7 +3719,7 @@ namespace bgfx
 	///
 	/// @attention C99 equivalent is `bgfx_dispatch_indirect`.
 	///
-	uint32_t dispatch(
+	void dispatch(
 		  uint8_t _id
 		, ProgramHandle _handle
 		, IndirectBufferHandle _indirectHandle

+ 7 - 6
include/bgfx/c99/bgfx.h

@@ -482,6 +482,7 @@ typedef struct bgfx_caps_limits
     uint32_t maxDynamicVertexBuffers;
     uint32_t maxUniforms;
     uint32_t maxOcclusionQueries;
+    uint32_t maxEncoders;
 
 } bgfx_caps_limits_t;
 
@@ -906,16 +907,16 @@ BGFX_C_API void bgfx_set_instance_data_from_dynamic_vertex_buffer(bgfx_dynamic_v
 BGFX_C_API void bgfx_set_texture(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint32_t _flags);
 
 /**/
-BGFX_C_API uint32_t bgfx_touch(uint8_t _id);
+BGFX_C_API void bgfx_touch(uint8_t _id);
 
 /**/
-BGFX_C_API uint32_t bgfx_submit(uint8_t _id, bgfx_program_handle_t _handle, int32_t _depth, bool _preserveState);
+BGFX_C_API void bgfx_submit(uint8_t _id, bgfx_program_handle_t _handle, int32_t _depth, bool _preserveState);
 
 /**/
-BGFX_C_API uint32_t bgfx_submit_occlusion_query(uint8_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, int32_t _depth, bool _preserveState);
+BGFX_C_API void bgfx_submit_occlusion_query(uint8_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, int32_t _depth, bool _preserveState);
 
 /**/
-BGFX_C_API uint32_t bgfx_submit_indirect(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState);
+BGFX_C_API void bgfx_submit_indirect(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState);
 
 /**/
 BGFX_C_API void bgfx_set_image(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format);
@@ -936,10 +937,10 @@ BGFX_C_API void bgfx_set_compute_dynamic_vertex_buffer(uint8_t _stage, bgfx_dyna
 BGFX_C_API void bgfx_set_compute_indirect_buffer(uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access);
 
 /**/
-BGFX_C_API uint32_t bgfx_dispatch(uint8_t _id, bgfx_program_handle_t _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags);
+BGFX_C_API void bgfx_dispatch(uint8_t _id, bgfx_program_handle_t _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags);
 
 /**/
-BGFX_C_API uint32_t bgfx_dispatch_indirect(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags);
+BGFX_C_API void bgfx_dispatch_indirect(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags);
 
 /**/
 BGFX_C_API void bgfx_discard();

+ 6 - 6
include/bgfx/c99/platform.h

@@ -184,18 +184,18 @@ typedef struct bgfx_interface_vtbl
     void (*set_instance_data_from_vertex_buffer)(bgfx_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _num);
     void (*set_instance_data_from_dynamic_vertex_buffer)(bgfx_dynamic_vertex_buffer_handle_t _handle, uint32_t _startVertex, uint32_t _num);
     void (*set_texture)(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint32_t _flags);
-    uint32_t (*touch)(uint8_t _id);
-    uint32_t (*submit)(uint8_t _id, bgfx_program_handle_t _handle, int32_t _depth, bool _preserveState);
-    uint32_t (*submit_occlusion_query)(uint8_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, int32_t _depth, bool _preserveState);
-    uint32_t (*submit_indirect)(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState);
+    void (*touch)(uint8_t _id);
+    void (*submit)(uint8_t _id, bgfx_program_handle_t _handle, int32_t _depth, bool _preserveState);
+    void (*submit_occlusion_query)(uint8_t _id, bgfx_program_handle_t _program, bgfx_occlusion_query_handle_t _occlusionQuery, int32_t _depth, bool _preserveState);
+    void (*submit_indirect)(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState);
     void (*set_image)(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format);
     void (*set_compute_index_buffer)(uint8_t _stage, bgfx_index_buffer_handle_t _handle, bgfx_access_t _access);
     void (*set_compute_vertex_buffer)(uint8_t _stage, bgfx_vertex_buffer_handle_t _handle, bgfx_access_t _access);
     void (*set_compute_dynamic_index_buffer)(uint8_t _stage, bgfx_dynamic_index_buffer_handle_t _handle, bgfx_access_t _access);
     void (*set_compute_dynamic_vertex_buffer)(uint8_t _stage, bgfx_dynamic_vertex_buffer_handle_t _handle, bgfx_access_t _access);
     void (*set_compute_indirect_buffer)(uint8_t _stage, bgfx_indirect_buffer_handle_t _handle, bgfx_access_t _access);
-    uint32_t (*dispatch)(uint8_t _id, bgfx_program_handle_t _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags);
-    uint32_t (*dispatch_indirect)(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags);
+    void (*dispatch)(uint8_t _id, bgfx_program_handle_t _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags);
+    void (*dispatch_indirect)(uint8_t _id, bgfx_program_handle_t _handle, bgfx_indirect_buffer_handle_t _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags);
     void (*discard)();
     void (*blit)(uint8_t _id, bgfx_texture_handle_t _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, bgfx_texture_handle_t _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth);
     void (*request_screen_shot)(bgfx_frame_buffer_handle_t _handle, const char* _filePath);

+ 1 - 1
include/bgfx/defines.h

@@ -6,7 +6,7 @@
 #ifndef BGFX_DEFINES_H_HEADER_GUARD
 #define BGFX_DEFINES_H_HEADER_GUARD
 
-#define BGFX_API_VERSION UINT32_C(53)
+#define BGFX_API_VERSION UINT32_C(54)
 
 /// Color RGB/alpha/depth write. When it's not specified write will be disabled.
 #define BGFX_STATE_RGB_WRITE               UINT64_C(0x0000000000000001) //!< Enable RGB write.

Fișier diff suprimat deoarece este prea mare
+ 356 - 116
src/bgfx.cpp


+ 175 - 46
src/bgfx_p.h

@@ -44,6 +44,12 @@
 				, _handleAlloc.getMaxHandles() \
 				)
 
+#if BGFX_CONFIG_MULTITHREADED
+#	define BGFX_MUTEX_SCOPE(_mutex) bx::MutexScope BX_CONCATENATE(mutexScope, __LINE__)(_mutex)
+#else
+#	define BGFX_MUTEX_SCOPE(_mutex) BX_NOOP()
+#endif // BGFX_CONFIG_MULTITHREADED
+
 #if BGFX_CONFIG_PROFILER
 #	define BGFX_PROFILER_SCOPE(_name, _abgr) ProfilerScope BX_CONCATENATE(profilerScope, __LINE__)(_name, _abgr, __FILE__, uint16_t(__LINE__) )
 #	define BGFX_PROFILER_BEGIN(_name, _abgr) g_callback->profilerBeginLiteral(_name, _abgr, __FILE__, uint16_t(__LINE__) )
@@ -110,6 +116,7 @@ namespace bgfx
 #include <bx/hash.h>
 #include <bx/maputil.h>
 #include <bx/math.h>
+#include <bx/mutex.h>
 #include <bx/os.h>
 #include <bx/readerwriter.h>
 #include <bx/ringbuffer.h>
@@ -1762,8 +1769,8 @@ namespace bgfx
 		FrameCache m_frameCache;
 		UniformBuffer* m_uniformBuffer;
 
-		RenderItemCount m_numRenderItems;
-		RenderItemCount m_numDropped;
+		uint32_t m_numRenderItems;
+		uint32_t m_numDropped;
 		uint16_t m_numBlitItems;
 
 		uint32_t m_iboffset;
@@ -1860,7 +1867,12 @@ namespace bgfx
 			discard();
 		}
 
-		void frame()
+		void begin(Frame* _frame)
+		{
+			m_frame = _frame;
+		}
+
+		void end()
 		{
 			if (BX_ENABLED(BGFX_CONFIG_DEBUG_OCCLUSION) )
 			{
@@ -1873,12 +1885,12 @@ namespace bgfx
 			}
 		}
 
-		void setMarker(Frame* _frame, const char* _name)
+		void setMarker(const char* _name)
 		{
-			_frame->m_uniformBuffer->writeMarker(_name);
+			m_frame->m_uniformBuffer->writeMarker(_name);
 		}
 
-		void setUniform(Frame* _frame, UniformType::Enum _type, UniformHandle _handle, const void* _value, uint16_t _num)
+		void setUniform(UniformType::Enum _type, UniformHandle _handle, const void* _value, uint16_t _num)
 		{
 			if (BX_ENABLED(BGFX_CONFIG_DEBUG_UNIFORM) )
 			{
@@ -1890,8 +1902,8 @@ namespace bgfx
 				m_uniformSet.insert(_handle.idx);
 			}
 
-			UniformBuffer::update(_frame->m_uniformBuffer);
-			_frame->m_uniformBuffer->writeUniform(_type, _handle.idx, _value, _num);
+			UniformBuffer::update(m_frame->m_uniformBuffer);
+			m_frame->m_uniformBuffer->writeUniform(_type, _handle.idx, _value, _num);
 		}
 
 		void setState(uint64_t _state, uint32_t _rgba)
@@ -1915,9 +1927,9 @@ namespace bgfx
 			m_draw.m_stencil = packStencil(_fstencil, _bstencil);
 		}
 
-		uint16_t setScissor(FrameCache& _frameCache, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
+		uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
 		{
-			uint16_t scissor = (uint16_t)_frameCache.m_rectCache.add(_x, _y, _width, _height);
+			uint16_t scissor = (uint16_t)m_frame->m_frameCache.m_rectCache.add(_x, _y, _width, _height);
 			m_draw.m_scissor = scissor;
 			return scissor;
 		}
@@ -1927,18 +1939,18 @@ namespace bgfx
 			m_draw.m_scissor = _cache;
 		}
 
-		uint32_t setTransform(FrameCache& _frameCache, const void* _mtx, uint16_t _num)
+		uint32_t setTransform(const void* _mtx, uint16_t _num)
 		{
-			m_draw.m_startMatrix = _frameCache.m_matrixCache.add(_mtx, _num);
+			m_draw.m_startMatrix = m_frame->m_frameCache.m_matrixCache.add(_mtx, _num);
 			m_draw.m_numMatrices = _num;
 
 			return m_draw.m_startMatrix;
 		}
 
-		uint32_t allocTransform(FrameCache& _frameCache, Transform* _transform, uint16_t _num)
+		uint32_t allocTransform(Transform* _transform, uint16_t _num)
 		{
-			uint32_t first   = _frameCache.m_matrixCache.reserve(&_num);
-			_transform->data = _frameCache.m_matrixCache.toPtr(first);
+			uint32_t first   = m_frame->m_frameCache.m_matrixCache.reserve(&_num);
+			_transform->data = m_frame->m_frameCache.m_matrixCache.toPtr(first);
 			_transform->num  = _num;
 
 			return first;
@@ -2037,7 +2049,7 @@ namespace bgfx
 			m_draw.m_instanceDataBuffer = _handle;
 		}
 
-		void setTexture(Frame* _frame, uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags)
+		void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags)
 		{
 			Binding& bind = m_bind.m_bind[_stage];
 			bind.m_idx    = _handle.idx;
@@ -2050,7 +2062,7 @@ namespace bgfx
 			if (isValid(_sampler) )
 			{
 				uint32_t stage = _stage;
-				setUniform(_frame, UniformType::Int1, _sampler, &stage, 1);
+				setUniform(UniformType::Int1, _sampler, &stage, 1);
 			}
 		}
 
@@ -2074,7 +2086,7 @@ namespace bgfx
 			bind.m_un.m_compute.m_mip    = 0;
 		}
 
-		void setImage(Frame* _frame, uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format)
+		void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format)
 		{
 			Binding& bind = m_bind.m_bind[_stage];
 			bind.m_idx    = _handle.idx;
@@ -2086,7 +2098,7 @@ namespace bgfx
 			if (isValid(_sampler) )
 			{
 				uint32_t stage = _stage;
-				setUniform(_frame, UniformType::Int1, _sampler, &stage, 1);
+				setUniform(UniformType::Int1, _sampler, &stage, 1);
 			}
 		}
 
@@ -2104,28 +2116,30 @@ namespace bgfx
 			m_stateFlags = BGFX_STATE_NONE;
 		}
 
-		uint32_t submit(Frame* _frame, uint8_t _id, ProgramHandle _program, OcclusionQueryHandle _occlusionQuery, int32_t _depth, bool _preserveState);
+		void submit(uint8_t _id, ProgramHandle _program, OcclusionQueryHandle _occlusionQuery, int32_t _depth, bool _preserveState);
 
-		uint32_t submit(Frame* _frame, uint8_t _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState)
+		void submit(uint8_t _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState)
 		{
 			m_draw.m_startIndirect  = _start;
 			m_draw.m_numIndirect    = _num;
 			m_draw.m_indirectBuffer = _indirectHandle;
 			OcclusionQueryHandle handle = BGFX_INVALID_HANDLE;
-			return submit(_frame, _id, _program, handle, _depth, _preserveState);
+			submit(_id, _program, handle, _depth, _preserveState);
 		}
 
-		uint32_t dispatch(Frame* _frame, uint8_t _id, ProgramHandle _handle, uint32_t _ngx, uint32_t _ngy, uint32_t _ngz, uint8_t _flags);
+		void dispatch(uint8_t _id, ProgramHandle _handle, uint32_t _ngx, uint32_t _ngy, uint32_t _ngz, uint8_t _flags);
 
-		uint32_t dispatch(Frame* _frame, uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags)
+		void dispatch(uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags)
 		{
 			m_compute.m_indirectBuffer = _indirectHandle;
 			m_compute.m_startIndirect  = _start;
 			m_compute.m_numIndirect    = _num;
-			return dispatch(_frame, _id, _handle, 0, 0, 0, _flags);
+			dispatch(_id, _handle, 0, 0, 0, _flags);
 		}
 
-		void blit(Frame* _frame, uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth);
+		void blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth);
+
+		Frame* m_frame;
 
 		SortKey m_key;
 
@@ -2426,7 +2440,8 @@ namespace bgfx
 	struct Context
 	{
 		Context()
-			: m_render(&m_frame[0])
+			: m_numEncoders(1)
+			, m_render(&m_frame[0])
 			, m_submit(&m_frame[BGFX_CONFIG_MULTITHREADED ? 1 : 0])
 			, m_numFreeDynamicIndexBufferHandles(0)
 			, m_numFreeDynamicVertexBufferHandles(0)
@@ -2514,22 +2529,30 @@ namespace bgfx
 
 		BGFX_API_FUNC(void dbgTextClear(uint8_t _attr, bool _small) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			m_submit->m_textVideoMem->resize(_small, (uint16_t)m_resolution.m_width, (uint16_t)m_resolution.m_height);
 			m_submit->m_textVideoMem->clear(_attr);
 		}
 
 		BGFX_API_FUNC(void dbgTextPrintfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			m_submit->m_textVideoMem->printfVargs(_x, _y, _attr, _format, _argList);
 		}
 
 		BGFX_API_FUNC(void dbgTextImage(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const void* _data, uint16_t _pitch) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			m_submit->m_textVideoMem->image(_x, _y, _width, _height, _data, _pitch);
 		}
 
 		BGFX_API_FUNC(const HMD* getHMD() )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			if (m_submit->m_hmdInitialized)
 			{
 				return &m_submit->m_hmd;
@@ -2540,6 +2563,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(const Stats* getPerfStats() )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			Stats& stats = m_submit->m_perfStats;
 			const Resolution& resolution = m_submit->m_resolution;
 			stats.width  = uint16_t(resolution.m_width);
@@ -2552,6 +2577,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(IndexBufferHandle createIndexBuffer(const Memory* _mem, uint16_t _flags) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			IndexBufferHandle handle = { m_indexBufferHandle.alloc() };
 
 			BX_WARN(isValid(handle), "Failed to allocate index buffer handle.");
@@ -2572,6 +2599,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyIndexBuffer(IndexBufferHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyIndexBuffer", m_indexBufferHandle, _handle);
 			bool ok = m_submit->free(_handle); BX_UNUSED(ok);
 			BX_CHECK(ok, "Index buffer handle %d is already destroyed!", _handle.idx);
@@ -2598,6 +2627,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl, uint16_t _flags) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			VertexBufferHandle handle = { m_vertexBufferHandle.alloc() };
 
 			BX_WARN(isValid(handle), "Failed to allocate vertex buffer handle.");
@@ -2624,6 +2655,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyVertexBuffer(VertexBufferHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyVertexBuffer", m_vertexBufferHandle, _handle);
 			bool ok = m_submit->free(_handle); BX_UNUSED(ok);
 			BX_CHECK(ok, "Vertex buffer handle %d is already destroyed!", _handle.idx);
@@ -2673,6 +2706,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num, uint16_t _flags) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			DynamicIndexBufferHandle handle = BGFX_INVALID_HANDLE;
 			const uint32_t indexSize = 0 == (_flags & BGFX_BUFFER_INDEX32) ? 2 : 4;
 			uint32_t size = BX_ALIGN_16(_num*indexSize);
@@ -2721,6 +2756,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem, uint16_t _flags) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BX_CHECK(0 == (_flags &  BGFX_BUFFER_COMPUTE_READ_WRITE), "Cannot initialize compute buffer from CPU.");
 			const uint32_t indexSize = 0 == (_flags & BGFX_BUFFER_INDEX32) ? 2 : 4;
 			DynamicIndexBufferHandle handle = createDynamicIndexBuffer(_mem->size/indexSize, _flags);
@@ -2739,6 +2776,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _startIndex, const Memory* _mem) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("updateDynamicIndexBuffer", m_dynamicIndexBufferHandle, _handle);
 
 			DynamicIndexBuffer& dib = m_dynamicIndexBuffers[_handle.idx];
@@ -2776,6 +2815,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyDynamicIndexBuffer(DynamicIndexBufferHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyDynamicIndexBuffer", m_dynamicIndexBufferHandle, _handle);
 
 			m_freeDynamicIndexBufferHandle[m_numFreeDynamicIndexBufferHandles++] = _handle;
@@ -2834,6 +2875,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(DynamicVertexBufferHandle createDynamicVertexBuffer(uint32_t _num, const VertexDecl& _decl, uint16_t _flags) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			DynamicVertexBufferHandle handle = BGFX_INVALID_HANDLE;
 			uint32_t size = bx::strideAlign16(_num*_decl.m_stride, _decl.m_stride);
 
@@ -2881,6 +2924,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl, uint16_t _flags) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			uint32_t numVertices = _mem->size/_decl.m_stride;
 			DynamicVertexBufferHandle handle = createDynamicVertexBuffer(numVertices, _decl, _flags);
 
@@ -2898,6 +2943,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void updateDynamicVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _startVertex, const Memory* _mem) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("updateDynamicVertexBuffer", m_dynamicVertexBufferHandle, _handle);
 
 			DynamicVertexBuffer& dvb = m_dynamicVertexBuffers[_handle.idx];
@@ -2936,6 +2983,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyDynamicVertexBuffer", m_dynamicVertexBufferHandle, _handle);
 
 			m_freeDynamicVertexBufferHandle[m_numFreeDynamicVertexBufferHandles++] = _handle;
@@ -2975,13 +3024,17 @@ namespace bgfx
 			m_dynamicVertexBufferHandle.free(_handle.idx);
 		}
 
-		BGFX_API_FUNC(uint32_t getAvailTransientIndexBuffer(uint32_t _num) const)
+		BGFX_API_FUNC(uint32_t getAvailTransientIndexBuffer(uint32_t _num) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			return m_submit->getAvailTransientIndexBuffer(_num);
 		}
 
-		BGFX_API_FUNC(uint32_t getAvailTransientVertexBuffer(uint32_t _num, uint16_t _stride) const)
+		BGFX_API_FUNC(uint32_t getAvailTransientVertexBuffer(uint32_t _num, uint16_t _stride) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			return m_submit->getAvailTransientVertexBuffer(_num, _stride);
 		}
 
@@ -3020,6 +3073,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint32_t _num) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			uint32_t offset = m_submit->allocTransientIndexBuffer(_num);
 
 			TransientIndexBuffer& tib = *m_submit->m_transientIb;
@@ -3080,6 +3135,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexDecl& _decl) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			VertexDeclHandle declHandle = m_declRef.find(_decl.m_hash);
 
 			TransientVertexBuffer& dvb = *m_submit->m_transientVb;
@@ -3150,6 +3207,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(ShaderHandle createShader(const Memory* _mem) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			bx::MemoryReader reader(_mem->data, _mem->size);
 
 			bx::Error err;
@@ -3262,6 +3321,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(uint16_t getShaderUniforms(ShaderHandle _handle, UniformHandle* _uniforms, uint16_t _max) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			if (!isValid(_handle) )
 			{
 				BX_WARN(false, "Passing invalid shader handle to bgfx::getShaderUniforms.");
@@ -3288,6 +3349,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void setName(ShaderHandle _handle, const char* _name) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("setName", m_shaderHandle, _handle);
 
 			ShaderRef& sr = m_shaderRef[_handle.idx];
@@ -3298,6 +3361,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyShader(ShaderHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyShader", m_shaderHandle, _handle);
 
 			if (!isValid(_handle) )
@@ -3350,6 +3415,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(ProgramHandle createProgram(ShaderHandle _vsh, ShaderHandle _fsh, bool _destroyShaders) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			if (!isValid(_vsh)
 			||  !isValid(_fsh) )
 			{
@@ -3411,6 +3478,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(ProgramHandle createProgram(ShaderHandle _vsh, bool _destroyShader) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			if (!isValid(_vsh) )
 			{
 				BX_WARN(false, "Compute shader is invalid (vsh %d).", _vsh.idx);
@@ -3461,6 +3530,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyProgram(ProgramHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyProgram", m_programHandle, _handle);
 
 			ProgramRef& pr = m_programRef[_handle.idx];
@@ -3486,6 +3557,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info, BackbufferRatio::Enum _ratio) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			TextureInfo ti;
 			if (NULL == _info)
 			{
@@ -3544,6 +3617,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void setName(TextureHandle _handle, const char* _name) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("setName", m_textureHandle, _handle);
 
 			TextureRef& ref = m_textureRef[_handle.idx];
@@ -3554,6 +3629,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyTexture(TextureHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyTexture", m_textureHandle, _handle);
 
 			if (!isValid(_handle) )
@@ -3567,6 +3644,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(uint32_t readTexture(TextureHandle _handle, void* _data, uint8_t _mip) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("readTexture", m_textureHandle, _handle);
 
 			const TextureRef& ref = m_textureRef[_handle.idx];
@@ -3647,6 +3726,8 @@ namespace bgfx
 			, const Memory* _mem
 		) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateTexture);
 			cmdbuf.write(_handle);
 			cmdbuf.write(_side);
@@ -3688,6 +3769,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(FrameBufferHandle createFrameBuffer(uint8_t _num, const Attachment* _attachment, bool _destroyTextures) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BX_CHECK(checkFrameBuffer(_num, _attachment)
 				, "Too many frame buffer attachments (num attachments: %d, max color attachments %d)!"
 				, _num
@@ -3735,6 +3818,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(FrameBufferHandle createFrameBuffer(void* _nwh, uint16_t _width, uint16_t _height, TextureFormat::Enum _depthFormat) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			FrameBufferHandle handle = { m_frameBufferHandle.alloc() };
 			BX_WARN(isValid(handle), "Failed to allocate frame buffer handle.");
 
@@ -3758,6 +3843,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(TextureHandle getTexture(FrameBufferHandle _handle, uint8_t _attachment) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("getTexture", m_frameBufferHandle, _handle);
 
 			const FrameBufferRef& ref = m_frameBufferRef[_handle.idx];
@@ -3773,6 +3860,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyFrameBuffer(FrameBufferHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyFrameBuffer", m_frameBufferHandle, _handle);
 			bool ok = m_submit->free(_handle); BX_UNUSED(ok);
 			BX_CHECK(ok, "Frame buffer handle %d is already destroyed!", _handle.idx);
@@ -3796,6 +3885,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BX_WARN(PredefinedUniform::Count == nameToPredefinedUniformEnum(_name), "%s is predefined uniform name.", _name);
 			if (PredefinedUniform::Count != nameToPredefinedUniformEnum(_name) )
 			{
@@ -3871,6 +3962,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void getUniformInfo(UniformHandle _handle, UniformInfo& _info) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("getUniformInfo", m_uniformHandle, _handle);
 
 			UniformRef& uniform = m_uniformRef[_handle.idx];
@@ -3881,6 +3974,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyUniform(UniformHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyUniform", m_uniformHandle, _handle);
 
 			UniformRef& uniform = m_uniformRef[_handle.idx];
@@ -3902,6 +3997,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(OcclusionQueryHandle createOcclusionQuery() )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			OcclusionQueryHandle handle = { m_occlusionQueryHandle.alloc() };
 			if (isValid(handle) )
 			{
@@ -3916,6 +4013,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(OcclusionQueryResult::Enum getResult(OcclusionQueryHandle _handle, int32_t* _result) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("getResult", m_occlusionQueryHandle, _handle);
 
 			switch (m_submit->m_occlusion[_handle.idx])
@@ -3935,6 +4034,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void destroyOcclusionQuery(OcclusionQueryHandle _handle) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE("destroyOcclusionQuery", m_occlusionQueryHandle, _handle);
 
 			m_freeOcclusionQueryHandle[m_numFreeOcclusionQueryHandles++] = _handle;
@@ -3942,6 +4043,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void requestScreenShot(FrameBufferHandle _handle, const char* _filePath) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BGFX_CHECK_HANDLE_INVALID_OK("requestScreenShot", m_frameBufferHandle, _handle);
 
 			if (isValid(_handle) )
@@ -3963,6 +4066,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void setPaletteColor(uint8_t _index, const float _rgba[4]) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			BX_CHECK(_index < BGFX_CONFIG_MAX_COLOR_PALETTE, "Color palette index out of bounds %d (max: %d)."
 				, _index
 				, BGFX_CONFIG_MAX_COLOR_PALETTE
@@ -3973,6 +4078,8 @@ namespace bgfx
 
 		BGFX_API_FUNC(void setViewName(uint8_t _id, const char* _name) )
 		{
+			BGFX_MUTEX_SCOPE(m_resourceApiLock);
+
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::UpdateViewName);
 			cmdbuf.write(_id);
 			uint16_t len = (uint16_t)bx::strLen(_name)+1;
@@ -4111,7 +4218,7 @@ namespace bgfx
 
 		BGFX_API_FUNC(void setMarker(const char* _marker) )
 		{
-			m_encoder[0].setMarker(m_submit, _marker);
+			m_encoder[0].setMarker(_marker);
 		}
 
 		BGFX_API_FUNC(void setState(uint64_t _state, uint32_t _rgba) )
@@ -4131,7 +4238,7 @@ namespace bgfx
 
 		BGFX_API_FUNC(uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) )
 		{
-			return m_encoder[0].setScissor(m_submit->m_frameCache, _x, _y, _width, _height);
+			return m_encoder[0].setScissor(_x, _y, _width, _height);
 		}
 
 		BGFX_API_FUNC(void setScissor(uint16_t _cache) )
@@ -4141,12 +4248,12 @@ namespace bgfx
 
 		BGFX_API_FUNC(uint32_t setTransform(const void* _mtx, uint16_t _num) )
 		{
-			return m_encoder[0].setTransform(m_submit->m_frameCache, _mtx, _num);
+			return m_encoder[0].setTransform(_mtx, _num);
 		}
 
 		BGFX_API_FUNC(uint32_t allocTransform(Transform* _transform, uint16_t _num) )
 		{
-			return m_encoder[0].allocTransform(m_submit->m_frameCache, _transform, _num);
+			return m_encoder[0].allocTransform(_transform, _num);
 		}
 
 		BGFX_API_FUNC(void setTransform(uint32_t _cache, uint16_t _num) )
@@ -4160,7 +4267,7 @@ namespace bgfx
 			const UniformRef& uniform = m_uniformRef[_handle.idx];
 			BX_CHECK(isValid(_handle) && 0 < uniform.m_refCount, "Setting invalid uniform (handle %3d)!", _handle.idx);
 			BX_CHECK(_num == UINT16_MAX || uniform.m_num >= _num, "Truncated uniform update. %d (max: %d)", _num, uniform.m_num);
-			m_encoder[0].setUniform(m_submit, uniform.m_type, _handle, _value, bx::uint16_min(uniform.m_num, _num) );
+			m_encoder[0].setUniform(uniform.m_type, _handle, _value, bx::uint16_min(uniform.m_num, _num) );
 		}
 
 		BGFX_API_FUNC(void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices) )
@@ -4227,21 +4334,21 @@ namespace bgfx
 		BGFX_API_FUNC(void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags) )
 		{
 			BGFX_CHECK_HANDLE_INVALID_OK("setTexture/TextureHandle", m_textureHandle, _handle);
-			m_encoder[0].setTexture(m_submit, _stage, _sampler, _handle, _flags);
+			m_encoder[0].setTexture(_stage, _sampler, _handle, _flags);
 		}
 
-		BGFX_API_FUNC(uint32_t submit(uint8_t _id, ProgramHandle _program, OcclusionQueryHandle _occlusionQuery, int32_t _depth, bool _preserveState) )
+		BGFX_API_FUNC(void submit(uint8_t _id, ProgramHandle _program, OcclusionQueryHandle _occlusionQuery, int32_t _depth, bool _preserveState) )
 		{
 			BGFX_CHECK_HANDLE_INVALID_OK("submit", m_programHandle, _program);
 			BGFX_CHECK_HANDLE_INVALID_OK("submit", m_occlusionQueryHandle, _occlusionQuery);
-			return m_encoder[0].submit(m_submit, _id, _program, _occlusionQuery, _depth, _preserveState);
+			m_encoder[0].submit(_id, _program, _occlusionQuery, _depth, _preserveState);
 		}
 
-		BGFX_API_FUNC(uint32_t submit(uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState) )
+		BGFX_API_FUNC(void submit(uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState) )
 		{
 			BGFX_CHECK_HANDLE_INVALID_OK("submit", m_programHandle, _handle);
 			BGFX_CHECK_HANDLE("submit", m_vertexBufferHandle, _indirectHandle);
-			return m_encoder[0].submit(m_submit, _id, _handle, _indirectHandle, _start, _num, _depth, _preserveState);
+			m_encoder[0].submit(_id, _handle, _indirectHandle, _start, _num, _depth, _preserveState);
 		}
 
 		BGFX_API_FUNC(void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) )
@@ -4286,20 +4393,20 @@ namespace bgfx
 			BX_CHECK(_format != TextureFormat::BGRA8
 				, "Can't use TextureFormat::BGRA8 with compute, use TextureFormat::RGBA8 instead."
 				);
-			m_encoder[0].setImage(m_submit, _stage, _sampler, _handle, _mip, _access, _format);
+			m_encoder[0].setImage(_stage, _sampler, _handle, _mip, _access, _format);
 		}
 
-		BGFX_API_FUNC(uint32_t dispatch(uint8_t _id, ProgramHandle _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) )
+		BGFX_API_FUNC(void dispatch(uint8_t _id, ProgramHandle _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) )
 		{
 			BGFX_CHECK_HANDLE_INVALID_OK("dispatch", m_programHandle, _handle);
-			return m_encoder[0].dispatch(m_submit, _id, _handle, _numX, _numY, _numZ, _flags);
+			m_encoder[0].dispatch(_id, _handle, _numX, _numY, _numZ, _flags);
 		}
 
-		BGFX_API_FUNC(uint32_t dispatch(uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags) )
+		BGFX_API_FUNC(void dispatch(uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags) )
 		{
 			BGFX_CHECK_HANDLE_INVALID_OK("dispatch", m_programHandle, _handle);
 			BGFX_CHECK_HANDLE("dispatch", m_vertexBufferHandle, _indirectHandle);
-			return m_encoder[0].dispatch(m_submit, _id, _handle, _indirectHandle, _start, _num, _flags);
+			m_encoder[0].dispatch(_id, _handle, _indirectHandle, _start, _num, _flags);
 		}
 
 		BGFX_API_FUNC(void discard() )
@@ -4317,9 +4424,13 @@ namespace bgfx
 				, bimg::getName(bimg::TextureFormat::Enum(dst.m_format) )
 				);
 			BX_UNUSED(src, dst);
-			m_encoder[0].blit(m_submit, _id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth);
+			m_encoder[0].blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth);
 		}
 
+		BGFX_API_FUNC(Encoder* begin() );
+
+		BGFX_API_FUNC(void end(Encoder* _encoder) );
+
 		BGFX_API_FUNC(uint32_t frame(bool _capture = false) );
 
 		uint32_t getSeqIncr(uint8_t _id)
@@ -4389,8 +4500,21 @@ namespace bgfx
 			}
 		}
 
+		void encoderApiWait()
+		{
+			for (uint32_t ii = 1; ii < m_numEncoders; ++ii)
+			{
+				m_encoderApiSem.wait();
+			}
+
+			m_numEncoders = 1;
+		}
+
 		bx::Semaphore m_renderSem;
 		bx::Semaphore m_apiSem;
+		bx::Semaphore m_encoderApiSem;
+		bx::Mutex     m_encoderApiLock;
+		bx::Mutex     m_resourceApiLock;
 		bx::Thread m_thread;
 #else
 		void apiSemPost()
@@ -4410,9 +4534,14 @@ namespace bgfx
 		void renderSemWait()
 		{
 		}
+
+		void encoderApiWait()
+		{
+		}
 #endif // BGFX_CONFIG_MULTITHREADED
 
-		EncoderImpl m_encoder[1];
+		EncoderImpl   m_encoder[BGFX_CONFIG_MAX_ENCODERS];
+		uint32_t      m_numEncoders;
 
 		Frame m_frame[1+(BGFX_CONFIG_MULTITHREADED ? 1 : 0)];
 		Frame* m_render;

+ 4 - 0
src/config.h

@@ -326,4 +326,8 @@
 #	define BGFX_CONFIG_MIP_LOD_BIAS 0
 #endif // BGFX_CONFIG_MIP_LOD_BIAS
 
+#ifndef BGFX_CONFIG_MAX_ENCODERS
+#	define BGFX_CONFIG_MAX_ENCODERS ( (0 != BGFX_CONFIG_MULTITHREADED) ? 8 : 1)
+#endif // BGFX_CONFIG_MAX_ENCODERS
+
 #endif // BGFX_CONFIG_H_HEADER_GUARD

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff