diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index c06a210fa..aeedd7a93 100644 --- a/include/bgfx/bgfx.h +++ b/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 diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index a9d68fc9f..a376f3e06 100644 --- a/include/bgfx/c99/bgfx.h +++ b/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(); diff --git a/include/bgfx/c99/platform.h b/include/bgfx/c99/platform.h index b2fab719f..84a1b68eb 100644 --- a/include/bgfx/c99/platform.h +++ b/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); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 748540a7f..cea889cc4 100644 --- a/include/bgfx/defines.h +++ b/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. diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 1e8e759ab..d31ad4aa9 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -16,15 +16,15 @@ BX_ERROR_RESULT(BGFX_ERROR_TEXTURE_VALIDATION, BX_MAKEFOURCC('b', 'g', 0, 1) ); namespace bgfx { -#define BGFX_MAIN_THREAD_MAGIC UINT32_C(0x78666762) +#define BGFX_API_THREAD_MAGIC UINT32_C(0x78666762) #if BGFX_CONFIG_MULTITHREADED -# define BGFX_CHECK_MAIN_THREAD() \ +# define BGFX_CHECK_API_THREAD() \ BX_CHECK(NULL != s_ctx, "Library is not initialized yet."); \ - BX_CHECK(BGFX_MAIN_THREAD_MAGIC == s_threadIndex, "Must be called from main thread.") -# define BGFX_CHECK_RENDER_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC != s_threadIndex, "Must be called from render thread.") + BX_CHECK(BGFX_API_THREAD_MAGIC == s_threadIndex, "Must be called from main thread.") +# define BGFX_CHECK_RENDER_THREAD() BX_CHECK(BGFX_API_THREAD_MAGIC != s_threadIndex, "Must be called from render thread.") #else -# define BGFX_CHECK_MAIN_THREAD() +# define BGFX_CHECK_API_THREAD() # define BGFX_CHECK_RENDER_THREAD() #endif // BGFX_CONFIG_MULTITHREADED @@ -588,7 +588,7 @@ namespace bgfx void TextVideoMemBlitter::init() { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); m_decl .begin() .add(Attrib::Position, 3, AttribType::Float) @@ -628,7 +628,7 @@ namespace bgfx void TextVideoMemBlitter::shutdown() { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); if (isValid(m_program) ) { @@ -748,7 +748,7 @@ namespace bgfx void ClearQuad::init() { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); if (RendererType::Noop != g_caps.rendererType) { @@ -778,7 +778,7 @@ namespace bgfx void ClearQuad::shutdown() { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); if (RendererType::Noop != g_caps.rendererType) { @@ -859,7 +859,7 @@ namespace bgfx return PredefinedUniform::Count; } - uint32_t EncoderImpl::submit(Frame* _frame, uint8_t _id, ProgramHandle _program, OcclusionQueryHandle _occlusionQuery, int32_t _depth, bool _preserveState) + void EncoderImpl::submit(uint8_t _id, ProgramHandle _program, OcclusionQueryHandle _occlusionQuery, int32_t _depth, bool _preserveState) { if (BX_ENABLED(BGFX_CONFIG_DEBUG_UNIFORM) && !_preserveState) @@ -880,17 +880,26 @@ namespace bgfx if (m_discard) { discard(); - return _frame->m_numRenderItems; + return; } - if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= _frame->m_numRenderItems - || (0 == m_draw.m_numVertices && 0 == m_draw.m_numIndices) ) + if (0 == m_draw.m_numVertices + && 0 == m_draw.m_numIndices) { - ++_frame->m_numDropped; - return _frame->m_numRenderItems; + discard(); + ++m_frame->m_numDropped; + return; } - _frame->m_uniformEnd = _frame->m_uniformBuffer->getPos(); + const uint32_t renderItemIdx = bx::atomicFetchAndAddsat(&m_frame->m_numRenderItems, 1, BGFX_CONFIG_MAX_DRAW_CALLS); + if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= renderItemIdx) + { + discard(); + ++m_frame->m_numDropped; + return; + } + + m_frame->m_uniformEnd = m_frame->m_uniformBuffer->getPos(); m_key.m_program = kInvalidHandle == _program.idx ? 0 @@ -910,13 +919,11 @@ namespace bgfx uint64_t key = m_key.encodeDraw(type); - const RenderItemCount numRenderItems = _frame->m_numRenderItems++; + m_frame->m_sortKeys[renderItemIdx] = key; + m_frame->m_sortValues[renderItemIdx] = RenderItemCount(renderItemIdx); - _frame->m_sortKeys[numRenderItems] = key; - _frame->m_sortValues[numRenderItems] = numRenderItems; - - m_draw.m_uniformBegin = _frame->m_uniformBegin; - m_draw.m_uniformEnd = _frame->m_uniformEnd; + m_draw.m_uniformBegin = m_frame->m_uniformBegin; + m_draw.m_uniformEnd = m_frame->m_uniformEnd; m_draw.m_stateFlags |= m_stateFlags; uint32_t numVertices = UINT32_MAX; @@ -939,21 +946,19 @@ namespace bgfx m_draw.m_occlusionQuery = _occlusionQuery; } - _frame->m_renderItem[numRenderItems].draw = m_draw; - _frame->m_renderItemBind[numRenderItems] = m_bind; + m_frame->m_renderItem[renderItemIdx].draw = m_draw; + m_frame->m_renderItemBind[renderItemIdx] = m_bind; if (!_preserveState) { m_draw.clear(); m_bind.clear(); - _frame->m_uniformBegin = _frame->m_uniformEnd; + m_frame->m_uniformBegin = m_frame->m_uniformEnd; m_stateFlags = BGFX_STATE_NONE; } - - return numRenderItems+1; } - uint32_t EncoderImpl::dispatch(Frame* _frame, uint8_t _id, ProgramHandle _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) + void EncoderImpl::dispatch(uint8_t _id, ProgramHandle _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) { if (BX_ENABLED(BGFX_CONFIG_DEBUG_UNIFORM) ) { @@ -963,16 +968,18 @@ namespace bgfx if (m_discard) { discard(); - return _frame->m_numRenderItems; + return; } - if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= _frame->m_numRenderItems) + const uint32_t renderItemIdx = bx::atomicFetchAndAddsat(&m_frame->m_numRenderItems, 1, BGFX_CONFIG_MAX_DRAW_CALLS); + if (BGFX_CONFIG_MAX_DRAW_CALLS-1 <= renderItemIdx) { - ++_frame->m_numDropped; - return _frame->m_numRenderItems; + discard(); + ++m_frame->m_numDropped; + return; } - _frame->m_uniformEnd = _frame->m_uniformBuffer->getPos(); + m_frame->m_uniformEnd = m_frame->m_uniformBuffer->getPos(); m_compute.m_startMatrix = m_draw.m_startMatrix; m_compute.m_numMatrices = m_draw.m_numMatrices; @@ -986,35 +993,31 @@ namespace bgfx m_key.m_view = _id; m_key.m_seq = s_ctx->getSeqIncr(_id); - const RenderItemCount numRenderItems = _frame->m_numRenderItems++; - uint64_t key = m_key.encodeCompute(); - _frame->m_sortKeys[numRenderItems] = key; - _frame->m_sortValues[numRenderItems] = numRenderItems; + m_frame->m_sortKeys[renderItemIdx] = key; + m_frame->m_sortValues[renderItemIdx] = renderItemIdx; - m_compute.m_uniformBegin = _frame->m_uniformBegin; - m_compute.m_uniformEnd = _frame->m_uniformEnd; - _frame->m_renderItem[numRenderItems].compute = m_compute; - _frame->m_renderItemBind[numRenderItems] = m_bind; + m_compute.m_uniformBegin = m_frame->m_uniformBegin; + m_compute.m_uniformEnd = m_frame->m_uniformEnd; + m_frame->m_renderItem[renderItemIdx].compute = m_compute; + m_frame->m_renderItemBind[renderItemIdx] = m_bind; m_compute.clear(); m_bind.clear(); - _frame->m_uniformBegin = _frame->m_uniformEnd; - - return numRenderItems+1; + m_frame->m_uniformBegin = m_frame->m_uniformEnd; } - void EncoderImpl::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 EncoderImpl::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) { - BX_WARN(_frame->m_numBlitItems < BGFX_CONFIG_MAX_BLIT_ITEMS + BX_WARN(m_frame->m_numBlitItems < BGFX_CONFIG_MAX_BLIT_ITEMS , "Exceed number of available blit items per frame. BGFX_CONFIG_MAX_BLIT_ITEMS is %d. Skipping blit." , BGFX_CONFIG_MAX_BLIT_ITEMS ); - if (_frame->m_numBlitItems < BGFX_CONFIG_MAX_BLIT_ITEMS) + if (m_frame->m_numBlitItems < BGFX_CONFIG_MAX_BLIT_ITEMS) { - uint16_t item = _frame->m_numBlitItems++; + uint16_t item = m_frame->m_numBlitItems++; - BlitItem& bi = _frame->m_blitItem[item]; + BlitItem& bi = m_frame->m_blitItem[item]; bi.m_srcX = _srcX; bi.m_srcY = _srcY; bi.m_srcZ = _srcZ; @@ -1032,7 +1035,7 @@ namespace bgfx BlitKey key; key.m_view = _id; key.m_item = item; - _frame->m_blitKeys[item] = key.encode(); + m_frame->m_blitKeys[item] = key.encode(); } } @@ -1066,7 +1069,7 @@ namespace bgfx if (NULL == s_ctx) { s_renderFrameCalled = true; - s_threadIndex = ~BGFX_MAIN_THREAD_MAGIC; + s_threadIndex = ~BGFX_API_THREAD_MAGIC; return RenderFrame::NoContext; } @@ -1255,6 +1258,7 @@ namespace bgfx LIMITS(maxDynamicVertexBuffers); LIMITS(maxUniforms); LIMITS(maxOcclusionQueries); + LIMITS(maxEncoders); #undef LIMITS BX_TRACE(""); @@ -1390,7 +1394,7 @@ namespace bgfx // should not be created. BX_TRACE("Application called bgfx::renderFrame directly, not creating render thread."); m_singleThreaded = true - && ~BGFX_MAIN_THREAD_MAGIC == s_threadIndex + && ~BGFX_API_THREAD_MAGIC == s_threadIndex ; } else @@ -1406,7 +1410,7 @@ namespace bgfx BX_TRACE("Running in %s-threaded mode", m_singleThreaded ? "single" : "multi"); - s_threadIndex = BGFX_MAIN_THREAD_MAGIC; + s_threadIndex = BGFX_API_THREAD_MAGIC; for (uint32_t ii = 0; ii < BX_COUNTOF(m_viewRemap); ++ii) { @@ -1433,6 +1437,8 @@ namespace bgfx frameNoRenderWait(); + m_encoder[0].begin(m_submit); + // Make sure renderer init is called from render thread. // g_caps is initialized and available after this point. frame(); @@ -1518,6 +1524,8 @@ namespace bgfx getCommandBuffer(CommandBuffer::RendererShutdownEnd); frame(); + m_encoder[0].end(); + m_dynVertexBufferAllocator.compact(); m_dynIndexBufferAllocator.compact(); @@ -1668,9 +1676,45 @@ namespace bgfx } } + Encoder* Context::begin() + { + EncoderImpl* encoder = &m_encoder[0]; + + if (BGFX_API_THREAD_MAGIC != s_threadIndex) + { + bx::MutexScope scopeLock(m_encoderApiLock); + + if (BGFX_CONFIG_MAX_ENCODERS == m_numEncoders ) + { + return NULL; + } + + uint32_t idx = m_numEncoders++; + encoder = &m_encoder[idx]; + encoder->begin(m_frame); + } + + return reinterpret_cast(encoder); + } + + void Context::end(Encoder* _encoder) + { + if (BGFX_API_THREAD_MAGIC != s_threadIndex) + { + EncoderImpl* encoder = reinterpret_cast(_encoder); + encoder->end(); + + m_encoderApiSem.post(); + } + } + uint32_t Context::frame(bool _capture) { - m_encoder[0].frame(); + bx::MutexScope resourceApiScope(m_resourceApiLock); + bx::MutexScope encoderApiScope(m_encoderApiLock); + encoderApiWait(); + + m_encoder[0].end(); m_submit->m_capture = _capture; BGFX_PROFILER_SCOPE("bgfx/API thread frame", 0xff2040ff); @@ -1678,6 +1722,8 @@ namespace bgfx renderSemWait(); frameNoRenderWait(); + m_encoder[0].begin(m_submit); + return m_frames; } @@ -2747,6 +2793,7 @@ namespace bgfx g_caps.limits.maxUniforms = BGFX_CONFIG_MAX_UNIFORMS; g_caps.limits.maxOcclusionQueries = BGFX_CONFIG_MAX_OCCLUSION_QUERIES; g_caps.limits.maxFBAttachments = 1; + g_caps.limits.maxEncoders = BGFX_CONFIG_MAX_ENCODERS; g_caps.vendorId = _vendorId; g_caps.deviceId = _deviceId; @@ -2798,7 +2845,7 @@ error: { BX_TRACE("Shutdown..."); - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); Context* ctx = s_ctx; // it's going to be NULLd inside shutdown. ctx->shutdown(); BX_CHECK(NULL == s_ctx, "bgfx is should be uninitialized here."); @@ -2832,14 +2879,260 @@ error: void reset(uint32_t _width, uint32_t _height, uint32_t _flags) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(0 == (_flags&BGFX_RESET_RESERVED_MASK), "Do not set reset reserved flags!"); s_ctx->reset(_width, _height, _flags); } + Encoder* begin() + { + return s_ctx->begin(); + } + +#define BGFX_ENCODER(_func) reinterpret_cast(this)->_func + + void Encoder::setMarker(const char* _marker) + { + BGFX_ENCODER(setMarker(_marker) ); + } + + void Encoder::setState(uint64_t _state, uint32_t _rgba) + { + BX_CHECK(0 == (_state&BGFX_STATE_RESERVED_MASK), "Do not set state reserved flags!"); + BGFX_ENCODER(setState(_state, _rgba) ); + } + + void Encoder::setCondition(OcclusionQueryHandle _handle, bool _visible) + { + BGFX_CHECK_CAPS(BGFX_CAPS_OCCLUSION_QUERY, "Occlusion query is not supported!"); + BGFX_ENCODER(setCondition(_handle, _visible) ); + } + + void Encoder::setStencil(uint32_t _fstencil, uint32_t _bstencil) + { + BGFX_ENCODER(setStencil(_fstencil, _bstencil) ); + } + + uint16_t Encoder::setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) + { + return BGFX_ENCODER(setScissor(_x, _y, _width, _height) ); + } + + void Encoder::setScissor(uint16_t _cache) + { + BGFX_ENCODER(setScissor(_cache) ); + } + + uint32_t Encoder::setTransform(const void* _mtx, uint16_t _num) + { + return BGFX_ENCODER(setTransform(_mtx, _num) ); + } + + uint32_t Encoder::allocTransform(Transform* _transform, uint16_t _num) + { + return BGFX_ENCODER(allocTransform(_transform, _num) ); + } + + void Encoder::setTransform(uint32_t _cache, uint16_t _num) + { + BGFX_ENCODER(setTransform(_cache, _num) ); + } + + void Encoder::setUniform(UniformHandle _handle, const void* _value, uint16_t _num) + { + const Context::UniformRef& uniform = s_ctx->m_uniformRef[_handle.idx]; + BGFX_ENCODER(setUniform(uniform.m_type, _handle, _value, _num) ); + } + + void Encoder::setIndexBuffer(IndexBufferHandle _handle) + { + setIndexBuffer(_handle, 0, UINT32_MAX); + } + + void Encoder::setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices) + { + BGFX_ENCODER(setIndexBuffer(_handle, _firstIndex, _numIndices) ); + } + + void Encoder::setIndexBuffer(DynamicIndexBufferHandle _handle) + { + setIndexBuffer(_handle, 0, UINT32_MAX); + } + + void Encoder::setIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices) + { + const DynamicIndexBuffer& dib = s_ctx->m_dynamicIndexBuffers[_handle.idx]; + BGFX_ENCODER(setIndexBuffer(dib, _firstIndex, _numIndices) ); + } + + void Encoder::setIndexBuffer(const TransientIndexBuffer* _tib) + { + setIndexBuffer(_tib, 0, UINT32_MAX); + } + + void Encoder::setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices) + { + BX_CHECK(NULL != _tib, "_tib can't be NULL"); + BGFX_ENCODER(setIndexBuffer(_tib, _firstIndex, _numIndices) ); + } + + void Encoder::setVertexBuffer(uint8_t _stream, VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices) + { + BGFX_ENCODER(setVertexBuffer(_stream, _handle, _startVertex, _numVertices) ); + } + + void Encoder::setVertexBuffer(uint8_t _stream, VertexBufferHandle _handle) + { + setVertexBuffer(_stream, _handle, 0, UINT32_MAX); + } + + void Encoder::setVertexBuffer(uint8_t _stream, DynamicVertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices) + { + const DynamicVertexBuffer& dvb = s_ctx->m_dynamicVertexBuffers[_handle.idx]; + BGFX_ENCODER(setVertexBuffer(_stream, dvb, _startVertex, _numVertices) ); + } + + void Encoder::setVertexBuffer(uint8_t _stream, DynamicVertexBufferHandle _handle) + { + setVertexBuffer(_stream, _handle, 0, UINT32_MAX); + } + + void Encoder::setVertexBuffer(uint8_t _stream, const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices) + { + BX_CHECK(NULL != _tvb, "_tvb can't be NULL"); + BGFX_ENCODER(setVertexBuffer(_stream, _tvb, _startVertex, _numVertices) ); + } + + void Encoder::setVertexBuffer(uint8_t _stream, const TransientVertexBuffer* _tvb) + { + setVertexBuffer(_stream, _tvb, 0, UINT32_MAX); + } + +// void Encoder::setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint32_t _num) +// { +// BX_CHECK(NULL != _idb, "_idb can't be NULL"); +// BGFX_ENCODER(setInstanceDataBuffer(_idb, _num) ); +// } + +// void Encoder::setInstanceDataBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _num) +// { +// BGFX_ENCODER(setInstanceDataBuffer(_handle, _startVertex, _num) ); +// } + +// void Encoder::setInstanceDataBuffer(DynamicVertexBufferHandle _handle, uint32_t _startVertex, uint32_t _num) +// { +// BGFX_ENCODER(setInstanceDataBuffer(_handle, _startVertex, _num) ); +// } + + void Encoder::setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags) + { + BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BGFX_ENCODER(setTexture(_stage, _sampler, _handle, _flags) ); + } + + void Encoder::touch(uint8_t _id) + { + ProgramHandle handle = BGFX_INVALID_HANDLE; + submit(_id, handle); + } + + void Encoder::submit(uint8_t _id, ProgramHandle _program, int32_t _depth, bool _preserveState) + { + OcclusionQueryHandle handle = BGFX_INVALID_HANDLE; + submit(_id, _program, handle, _depth, _preserveState); + } + + void Encoder::submit(uint8_t _id, ProgramHandle _program, OcclusionQueryHandle _occlusionQuery, int32_t _depth, bool _preserveState) + { + BX_CHECK(false + || !isValid(_occlusionQuery) + || 0 != (g_caps.supported & BGFX_CAPS_OCCLUSION_QUERY) + , "Occlusion query is not supported! Use bgfx::getCaps to check BGFX_CAPS_OCCLUSION_QUERY backend renderer capabilities." + ); + BGFX_ENCODER(submit(_id, _program, _occlusionQuery, _depth, _preserveState) ); + } + + void Encoder::submit(uint8_t _id, ProgramHandle _program, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, int32_t _depth, bool _preserveState) + { + BGFX_CHECK_CAPS(BGFX_CAPS_DRAW_INDIRECT, "Draw indirect is not supported!"); + BGFX_ENCODER(submit(_id, _program, _indirectHandle, _start, _num, _depth, _preserveState) ); + } + +// void Encoder::setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) +// { +// BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); +// BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); +// } + +// void Encoder::setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access) +// { +// BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); +// BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); +// } + +// void Encoder::setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access) +// { +// BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); +// BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); +// } + +// void Encoder::setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access) +// { +// BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); +// BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); +// } + +// void Encoder::setBuffer(uint8_t _stage, IndirectBufferHandle _handle, Access::Enum _access) +// { +// BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); +// BGFX_ENCODER(setBuffer(_stage, _handle, _access) ); +// } + + void Encoder::setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) + { + BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); + BGFX_ENCODER(setImage(_stage, _sampler, _handle, _mip, _access, _format) ); + } + + void Encoder::dispatch(uint8_t _id, ProgramHandle _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) + { + BGFX_CHECK_CAPS(BGFX_CAPS_COMPUTE, "Compute is not supported!"); + BGFX_ENCODER(dispatch(_id, _handle, _numX, _numY, _numZ, _flags) ); + } + + void Encoder::dispatch(uint8_t _id, ProgramHandle _handle, IndirectBufferHandle _indirectHandle, uint16_t _start, uint16_t _num, uint8_t _flags) + { + BGFX_CHECK_CAPS(BGFX_CAPS_DRAW_INDIRECT, "Dispatch indirect is not supported!"); + BGFX_CHECK_CAPS(BGFX_CAPS_COMPUTE, "Compute is not supported!"); + BGFX_ENCODER(dispatch(_id, _handle, _indirectHandle, _start, _num, _flags) ); + } + + void Encoder::discard() + { + BGFX_ENCODER(discard() ); + } + + void Encoder::blit(uint8_t _id, TextureHandle _dst, uint16_t _dstX, uint16_t _dstY, TextureHandle _src, uint16_t _srcX, uint16_t _srcY, uint16_t _width, uint16_t _height) + { + blit(_id, _dst, 0, _dstX, _dstY, 0, _src, 0, _srcX, _srcY, 0, _width, _height, 0); + } + + void Encoder::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) + { + BGFX_CHECK_CAPS(BGFX_CAPS_TEXTURE_BLIT, "Texture blit is not supported!"); + BGFX_ENCODER(blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth) ); + } + +#undef BGFX_ENCODER + + void end(Encoder* _encoder) + { + s_ctx->end(_encoder); + } + uint32_t frame(bool _capture) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); return s_ctx->frame(_capture); } @@ -2919,13 +3212,13 @@ error: void setDebug(uint32_t _debug) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setDebug(_debug); } void dbgTextClear(uint8_t _attr, bool _small) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->dbgTextClear(_attr, _small); } @@ -2936,7 +3229,7 @@ error: void dbgTextPrintf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); va_list argList; va_start(argList, _format); s_ctx->dbgTextPrintfVargs(_x, _y, _attr, _format, argList); @@ -2945,26 +3238,23 @@ error: void dbgTextImage(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const void* _data, uint16_t _pitch) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->dbgTextImage(_x, _y, _width, _height, _data, _pitch); } IndexBufferHandle createIndexBuffer(const Memory* _mem, uint16_t _flags) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); return s_ctx->createIndexBuffer(_mem, _flags); } void destroy(IndexBufferHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyIndexBuffer(_handle); } VertexBufferHandle createVertexBuffer(const Memory* _mem, const VertexDecl& _decl, uint16_t _flags) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); BX_CHECK(isValid(_decl), "Invalid VertexDecl."); return s_ctx->createVertexBuffer(_mem, _decl, _flags); @@ -2972,46 +3262,39 @@ error: void destroy(VertexBufferHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyVertexBuffer(_handle); } DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num, uint16_t _flags) { - BGFX_CHECK_MAIN_THREAD(); return s_ctx->createDynamicIndexBuffer(_num, _flags); } DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem, uint16_t _flags) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); return s_ctx->createDynamicIndexBuffer(_mem, _flags); } void updateDynamicIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _startIndex, const Memory* _mem) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); s_ctx->updateDynamicIndexBuffer(_handle, _startIndex, _mem); } void destroy(DynamicIndexBufferHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyDynamicIndexBuffer(_handle); } DynamicVertexBufferHandle createDynamicVertexBuffer(uint32_t _num, const VertexDecl& _decl, uint16_t _flags) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(isValid(_decl), "Invalid VertexDecl."); return s_ctx->createDynamicVertexBuffer(_num, _decl, _flags); } DynamicVertexBufferHandle createDynamicVertexBuffer(const Memory* _mem, const VertexDecl& _decl, uint16_t _flags) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); BX_CHECK(isValid(_decl), "Invalid VertexDecl."); return s_ctx->createDynamicVertexBuffer(_mem, _decl, _flags); @@ -3019,27 +3302,23 @@ error: void updateDynamicVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _startVertex, const Memory* _mem) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); s_ctx->updateDynamicVertexBuffer(_handle, _startVertex, _mem); } void destroy(DynamicVertexBufferHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyDynamicVertexBuffer(_handle); } uint32_t getAvailTransientIndexBuffer(uint32_t _num) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(0 < _num, "Requesting 0 indices."); return s_ctx->getAvailTransientIndexBuffer(_num); } uint32_t getAvailTransientVertexBuffer(uint32_t _num, const VertexDecl& _decl) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(0 < _num, "Requesting 0 vertices."); BX_CHECK(isValid(_decl), "Invalid VertexDecl."); return s_ctx->getAvailTransientVertexBuffer(_num, _decl.m_stride); @@ -3047,14 +3326,12 @@ error: uint32_t getAvailInstanceDataBuffer(uint32_t _num, uint16_t _stride) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(0 < _num, "Requesting 0 instances."); return s_ctx->getAvailTransientVertexBuffer(_num, _stride); } void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint32_t _num) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _tib, "_tib can't be NULL"); BX_CHECK(0 < _num, "Requesting 0 indices."); s_ctx->allocTransientIndexBuffer(_tib, _num); @@ -3066,7 +3343,6 @@ error: void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexDecl& _decl) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _tvb, "_tvb can't be NULL"); BX_CHECK(0 < _num, "Requesting 0 vertices."); BX_CHECK(UINT16_MAX >= _num, "Requesting %d vertices (max: %d).", _num, UINT16_MAX); @@ -3093,7 +3369,6 @@ error: void allocInstanceDataBuffer(InstanceDataBuffer* _idb, uint32_t _num, uint16_t _stride) { - BGFX_CHECK_MAIN_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_INSTANCING, "Instancing is not supported!"); BX_CHECK(_stride == BX_ALIGN_16(_stride), "Stride must be multiple of 16."); BX_CHECK(0 < _num, "Requesting 0 instanced data vertices."); @@ -3106,44 +3381,37 @@ error: IndirectBufferHandle createIndirectBuffer(uint32_t _num) { - BGFX_CHECK_MAIN_THREAD(); return s_ctx->createIndirectBuffer(_num); } void destroy(IndirectBufferHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyIndirectBuffer(_handle); } ShaderHandle createShader(const Memory* _mem) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); return s_ctx->createShader(_mem); } uint16_t getShaderUniforms(ShaderHandle _handle, UniformHandle* _uniforms, uint16_t _max) { - BGFX_CHECK_MAIN_THREAD(); return s_ctx->getShaderUniforms(_handle, _uniforms, _max); } void setName(ShaderHandle _handle, const char* _name) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->setName(_handle, _name); } void destroy(ShaderHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyShader(_handle); } ProgramHandle createProgram(ShaderHandle _vsh, ShaderHandle _fsh, bool _destroyShaders) { - BGFX_CHECK_MAIN_THREAD(); if (!isValid(_fsh) ) { return createProgram(_vsh, _destroyShaders); @@ -3154,13 +3422,11 @@ error: ProgramHandle createProgram(ShaderHandle _csh, bool _destroyShader) { - BGFX_CHECK_MAIN_THREAD(); return s_ctx->createProgram(_csh, _destroyShader); } void destroy(ProgramHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyProgram(_handle); } @@ -3287,7 +3553,6 @@ error: TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); return s_ctx->createTexture(_mem, _flags, _skip, _info, BackbufferRatio::Count); } @@ -3312,8 +3577,6 @@ error: static TextureHandle createTexture2D(BackbufferRatio::Enum _ratio, uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) { - BGFX_CHECK_MAIN_THREAD(); - bx::Error err; isTextureValid(0, false, _numLayers, _format, _flags, &err); BX_CHECK(err.isOk(), "%s (layers %d, format %s)" @@ -3379,8 +3642,6 @@ error: TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) { - BGFX_CHECK_MAIN_THREAD(); - bx::Error err; isTextureValid(_depth, false, 1, _format, _flags, &err); BX_CHECK(err.isOk(), "%s", err.getMessage().getPtr() ); @@ -3422,8 +3683,6 @@ error: TextureHandle createTextureCube(uint16_t _size, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) { - BGFX_CHECK_MAIN_THREAD(); - bx::Error err; isTextureValid(0, true, _numLayers, _format, _flags, &err); BX_CHECK(err.isOk(), "%s", err.getMessage().getPtr() ); @@ -3466,19 +3725,16 @@ error: void setName(TextureHandle _handle, const char* _name) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->setName(_handle, _name); } void destroy(TextureHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyTexture(_handle); } void updateTexture2D(TextureHandle _handle, uint16_t _layer, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const Memory* _mem, uint16_t _pitch) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); if (_width == 0 || _height == 0) @@ -3493,7 +3749,6 @@ error: void updateTexture3D(TextureHandle _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _z, uint16_t _width, uint16_t _height, uint16_t _depth, const Memory* _mem) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); BGFX_CHECK_CAPS(BGFX_CAPS_TEXTURE_3D, "Texture3D is not supported!"); @@ -3511,7 +3766,6 @@ error: void updateTextureCube(TextureHandle _handle, uint16_t _layer, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const Memory* _mem, uint16_t _pitch) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); BX_CHECK(_side <= 5, "Invalid side %d.", _side); if (0 == _width @@ -3527,7 +3781,6 @@ error: uint32_t readTexture(TextureHandle _handle, void* _data, uint8_t _mip) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _data, "_data can't be NULL"); BGFX_CHECK_CAPS(BGFX_CAPS_TEXTURE_READ_BACK, "Texture read-back is not supported!"); return s_ctx->readTexture(_handle, _data, _mip); @@ -3563,7 +3816,6 @@ error: FrameBufferHandle createFrameBuffer(uint8_t _num, const Attachment* _attachment, bool _destroyTextures) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(_num != 0, "Number of frame buffer attachments can't be 0."); BX_CHECK(_num <= BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS , "Number of frame buffer attachments is larger than allowed %d (max: %d)." @@ -3576,7 +3828,6 @@ error: FrameBufferHandle createFrameBuffer(void* _nwh, uint16_t _width, uint16_t _height, TextureFormat::Enum _depthFormat) { - BGFX_CHECK_MAIN_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_SWAP_CHAIN, "Swap chain is not supported!"); BX_WARN(_width > 0 && _height > 0 , "Invalid frame buffer dimensions (width %d, height %d)." @@ -3593,84 +3844,73 @@ error: TextureHandle getTexture(FrameBufferHandle _handle, uint8_t _attachment) { - BGFX_CHECK_MAIN_THREAD(); return s_ctx->getTexture(_handle, _attachment); } void destroy(FrameBufferHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyFrameBuffer(_handle); } UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num) { - BGFX_CHECK_MAIN_THREAD(); return s_ctx->createUniform(_name, _type, _num); } void getUniformInfo(UniformHandle _handle, UniformInfo& _info) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->getUniformInfo(_handle, _info); } void destroy(UniformHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->destroyUniform(_handle); } OcclusionQueryHandle createOcclusionQuery() { - BGFX_CHECK_MAIN_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_OCCLUSION_QUERY, "Occlusion query is not supported!"); return s_ctx->createOcclusionQuery(); } OcclusionQueryResult::Enum getResult(OcclusionQueryHandle _handle, int32_t* _result) { - BGFX_CHECK_MAIN_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_OCCLUSION_QUERY, "Occlusion query is not supported!"); return s_ctx->getResult(_handle, _result); } void destroy(OcclusionQueryHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_OCCLUSION_QUERY, "Occlusion query is not supported!"); s_ctx->destroyOcclusionQuery(_handle); } void setPaletteColor(uint8_t _index, uint32_t _rgba) { - BGFX_CHECK_MAIN_THREAD(); - const uint8_t rr = uint8_t(_rgba>>24); const uint8_t gg = uint8_t(_rgba>>16); const uint8_t bb = uint8_t(_rgba>> 8); const uint8_t aa = uint8_t(_rgba>> 0); - float rgba[4] = + const float rgba[4] = { rr * 1.0f/255.0f, gg * 1.0f/255.0f, bb * 1.0f/255.0f, aa * 1.0f/255.0f, }; + s_ctx->setPaletteColor(_index, rgba); } void setPaletteColor(uint8_t _index, float _r, float _g, float _b, float _a) { - BGFX_CHECK_MAIN_THREAD(); float rgba[4] = { _r, _g, _b, _a }; s_ctx->setPaletteColor(_index, rgba); } void setPaletteColor(uint8_t _index, const float _rgba[4]) { - BGFX_CHECK_MAIN_THREAD(); s_ctx->setPaletteColor(_index, _rgba); } @@ -3683,21 +3923,18 @@ error: void setViewName(uint8_t _id, const char* _name) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewName(_id, _name); } void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewRect(_id, _x, _y, _width, _height); } void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, BackbufferRatio::Enum _ratio) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); uint16_t width = uint16_t(s_ctx->m_resolution.m_width); @@ -3708,119 +3945,111 @@ error: void setViewScissor(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewScissor(_id, _x, _y, _width, _height); } void setViewClear(uint8_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewClear(_id, _flags, _rgba, _depth, _stencil); } void setViewClear(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewClear(_id, _flags, _depth, _stencil, _0, _1, _2, _3, _4, _5, _6, _7); } void setViewMode(uint8_t _id, ViewMode::Enum _mode) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewMode(_id, _mode); } void setViewFrameBuffer(uint8_t _id, FrameBufferHandle _handle) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewFrameBuffer(_id, _handle); } void setViewTransform(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags, const void* _projR) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewTransform(_id, _view, _projL, _flags, _projR); } void setViewOrder(uint8_t _id, uint8_t _num, const uint8_t* _order) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->setViewOrder(_id, _num, _order); } void resetView(uint8_t _id) { - BGFX_CHECK_MAIN_THREAD(); BX_CHECK(checkView(_id), "Invalid view id: %d", _id); s_ctx->resetView(_id); } void setMarker(const char* _marker) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setMarker(_marker); } void setState(uint64_t _state, uint32_t _rgba) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(0 == (_state&BGFX_STATE_RESERVED_MASK), "Do not set state reserved flags!"); s_ctx->setState(_state, _rgba); } void setCondition(OcclusionQueryHandle _handle, bool _visible) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_OCCLUSION_QUERY, "Occlusion query is not supported!"); s_ctx->setCondition(_handle, _visible); } void setStencil(uint32_t _fstencil, uint32_t _bstencil) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setStencil(_fstencil, _bstencil); } uint16_t setScissor(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); return s_ctx->setScissor(_x, _y, _width, _height); } void setScissor(uint16_t _cache) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setScissor(_cache); } uint32_t setTransform(const void* _mtx, uint16_t _num) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); return s_ctx->setTransform(_mtx, _num); } uint32_t allocTransform(Transform* _transform, uint16_t _num) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); return s_ctx->allocTransform(_transform, _num); } void setTransform(uint32_t _cache, uint16_t _num) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setTransform(_cache, _num); } void setUniform(UniformHandle _handle, const void* _value, uint16_t _num) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setUniform(_handle, _value, _num); } @@ -3831,7 +4060,7 @@ error: void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices); } @@ -3842,7 +4071,7 @@ error: void setIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices); } @@ -3853,14 +4082,14 @@ error: void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(NULL != _tib, "_tib can't be NULL"); s_ctx->setIndexBuffer(_tib, _firstIndex, _numIndices); } void setVertexBuffer(uint8_t _stream, VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setVertexBuffer(_stream, _handle, _startVertex, _numVertices); } @@ -3871,7 +4100,7 @@ error: void setVertexBuffer(uint8_t _stream, DynamicVertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setVertexBuffer(_stream, _handle, _startVertex, _numVertices); } @@ -3882,7 +4111,7 @@ error: void setVertexBuffer(uint8_t _stream, const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(NULL != _tvb, "_tvb can't be NULL"); s_ctx->setVertexBuffer(_stream, _tvb, _startVertex, _numVertices); } @@ -3894,120 +4123,120 @@ error: void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint32_t _num) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(NULL != _idb, "_idb can't be NULL"); s_ctx->setInstanceDataBuffer(_idb, _num); } void setInstanceDataBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _num) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setInstanceDataBuffer(_handle, _startVertex, _num); } void setInstanceDataBuffer(DynamicVertexBufferHandle _handle, uint32_t _startVertex, uint32_t _num) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->setInstanceDataBuffer(_handle, _startVertex, _num); } void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); s_ctx->setTexture(_stage, _sampler, _handle, _flags); } - uint32_t touch(uint8_t _id) + void touch(uint8_t _id) { ProgramHandle handle = BGFX_INVALID_HANDLE; - return submit(_id, handle); + submit(_id, handle); } - uint32_t submit(uint8_t _id, ProgramHandle _program, int32_t _depth, bool _preserveState) + void submit(uint8_t _id, ProgramHandle _program, int32_t _depth, bool _preserveState) { OcclusionQueryHandle handle = BGFX_INVALID_HANDLE; - return submit(_id, _program, handle, _depth, _preserveState); + submit(_id, _program, handle, _depth, _preserveState); } - uint32_t submit(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) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(false || !isValid(_occlusionQuery) || 0 != (g_caps.supported & BGFX_CAPS_OCCLUSION_QUERY) , "Occlusion query is not supported! Use bgfx::getCaps to check BGFX_CAPS_OCCLUSION_QUERY backend renderer capabilities." ); - return s_ctx->submit(_id, _program, _occlusionQuery, _depth, _preserveState); + s_ctx->submit(_id, _program, _occlusionQuery, _depth, _preserveState); } - uint32_t submit(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) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_DRAW_INDIRECT, "Draw indirect is not supported!"); - return s_ctx->submit(_id, _program, _indirectHandle, _start, _num, _depth, _preserveState); + s_ctx->submit(_id, _program, _indirectHandle, _start, _num, _depth, _preserveState); } void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); s_ctx->setBuffer(_stage, _handle, _access); } void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); s_ctx->setBuffer(_stage, _handle, _access); } void setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); s_ctx->setBuffer(_stage, _handle, _access); } void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); s_ctx->setBuffer(_stage, _handle, _access); } void setBuffer(uint8_t _stage, IndirectBufferHandle _handle, Access::Enum _access) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); s_ctx->setBuffer(_stage, _handle, _access); } void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BX_CHECK(_stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, "Invalid stage %d (max %d).", _stage, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS); s_ctx->setImage(_stage, _sampler, _handle, _mip, _access, _format); } - uint32_t dispatch(uint8_t _id, ProgramHandle _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) + void dispatch(uint8_t _id, ProgramHandle _handle, uint32_t _numX, uint32_t _numY, uint32_t _numZ, uint8_t _flags) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_COMPUTE, "Compute is not supported!"); - return s_ctx->dispatch(_id, _handle, _numX, _numY, _numZ, _flags); + s_ctx->dispatch(_id, _handle, _numX, _numY, _numZ, _flags); } - uint32_t dispatch(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) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_DRAW_INDIRECT, "Dispatch indirect is not supported!"); BGFX_CHECK_CAPS(BGFX_CAPS_COMPUTE, "Compute is not supported!"); - return s_ctx->dispatch(_id, _handle, _indirectHandle, _start, _num, _flags); + s_ctx->dispatch(_id, _handle, _indirectHandle, _start, _num, _flags); } void discard() { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->discard(); } @@ -4018,14 +4247,14 @@ error: 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) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); BGFX_CHECK_CAPS(BGFX_CAPS_TEXTURE_BLIT, "Texture blit is not supported!"); s_ctx->blit(_id, _dst, _dstMip, _dstX, _dstY, _dstZ, _src, _srcMip, _srcX, _srcY, _srcZ, _width, _height, _depth); } void requestScreenShot(FrameBufferHandle _handle, const char* _filePath) { - BGFX_CHECK_MAIN_THREAD(); + BGFX_CHECK_API_THREAD(); s_ctx->requestScreenShot(_handle, _filePath); } } // namespace bgfx @@ -4981,29 +5210,29 @@ BGFX_C_API void bgfx_set_texture(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx::setTexture(_stage, sampler.cpp, handle.cpp, _flags); } -BGFX_C_API uint32_t bgfx_touch(uint8_t _id) +BGFX_C_API void bgfx_touch(uint8_t _id) { return bgfx::touch(_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) { union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle }; - return bgfx::submit(_id, handle.cpp, _depth, _preserveState); + bgfx::submit(_id, handle.cpp, _depth, _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) { union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } program = { _program }; union { bgfx_occlusion_query_handle c; bgfx::OcclusionQueryHandle cpp; } occlusionQuery = { _occlusionQuery }; - return bgfx::submit(_id, program.cpp, occlusionQuery.cpp, _depth, _preserveState); + bgfx::submit(_id, program.cpp, occlusionQuery.cpp, _depth, _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) { union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle }; union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } indirectHandle = { _indirectHandle }; - return bgfx::submit(_id, handle.cpp, indirectHandle.cpp, _start, _num, _depth, _preserveState); + bgfx::submit(_id, handle.cpp, indirectHandle.cpp, _start, _num, _depth, _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) @@ -5043,17 +5272,17 @@ BGFX_C_API void bgfx_set_compute_indirect_buffer(uint8_t _stage, bgfx_indirect_b bgfx::setBuffer(_stage, handle.cpp, bgfx::Access::Enum(_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) { union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle }; - return bgfx::dispatch(_id, handle.cpp, _numX, _numY, _numZ, _flags); + bgfx::dispatch(_id, handle.cpp, _numX, _numY, _numZ, _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) { union { bgfx_program_handle_t c; bgfx::ProgramHandle cpp; } handle = { _handle }; union { bgfx_indirect_buffer_handle_t c; bgfx::IndirectBufferHandle cpp; } indirectHandle = { _indirectHandle }; - return bgfx::dispatch(_id, handle.cpp, indirectHandle.cpp, _start, _num, _flags); + bgfx::dispatch(_id, handle.cpp, indirectHandle.cpp, _start, _num, _flags); } BGFX_C_API void bgfx_discard() diff --git a/src/bgfx_p.h b/src/bgfx_p.h index ffdc05661..fdf082ca1 100644 --- a/src/bgfx_p.h +++ b/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 #include #include +#include #include #include #include @@ -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; diff --git a/src/config.h b/src/config.h index 34226e31c..7c0387158 100644 --- a/src/config.h +++ b/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