From 5ea84e82747c1495f659fc7c837fb7911f5e4b02 Mon Sep 17 00:00:00 2001 From: Branimir Karadzic Date: Wed, 8 Oct 2014 20:13:57 -0700 Subject: [PATCH] Added allocTransform API to return pointer to internal matrix cache. --- include/bgfx.h | 151 ++++++++++++++++++++++++++----------------------- src/bgfx.cpp | 12 ++++ src/bgfx_p.h | 85 ++++++++++++++++++++-------- 3 files changed, 153 insertions(+), 95 deletions(-) diff --git a/include/bgfx.h b/include/bgfx.h index 685dee7f..6f008ad0 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -95,7 +95,7 @@ namespace bgfx { Uint8, Int16, - Half, // Availability depends on: BGFX_CAPS_VERTEX_ATTRIB_HALF. + Half, // Availability depends on: `BGFX_CAPS_VERTEX_ATTRIB_HALF`. Float, Count @@ -200,7 +200,7 @@ namespace bgfx /// Callback interface to implement application specific behavior. /// Cached items are currently used only for OpenGL binary shaders. /// - /// NOTE: + /// @remarks /// 'fatal' callback can be called from any thread. Other callbacks /// are called from the render thread. /// @@ -240,6 +240,7 @@ namespace bgfx { } + /// struct Memory { uint8_t* data; @@ -273,6 +274,7 @@ namespace bgfx uint8_t formats[TextureFormat::Count]; }; + /// struct TransientIndexBuffer { uint8_t* data; @@ -281,6 +283,7 @@ namespace bgfx uint32_t startIndex; }; + /// struct TransientVertexBuffer { uint8_t* data; @@ -291,6 +294,7 @@ namespace bgfx VertexDeclHandle decl; }; + /// struct InstanceDataBuffer { uint8_t* data; @@ -301,15 +305,23 @@ namespace bgfx VertexBufferHandle handle; }; + /// struct TextureInfo { - TextureFormat::Enum format; - uint32_t storageSize; - uint16_t width; - uint16_t height; - uint16_t depth; - uint8_t numMips; - uint8_t bitsPerPixel; + TextureFormat::Enum format; //< Texture format. + uint32_t storageSize; //< Total amount of bytes required to store texture. + uint16_t width; //< Texture width. + uint16_t height; //< Texture height. + uint16_t depth; //< Texture depth. + uint8_t numMips; //< Number of MIP maps. + uint8_t bitsPerPixel; //< Format bits per pixel. + }; + + /// + struct Transform + { + float* data; //< Pointer to first matrix. + uint16_t num; //< Number of matrices. }; /// Vertex declaration. @@ -336,7 +348,7 @@ namespace bgfx /// vertexConvert for AttribType::Uint8 and AttribType::Int16. /// Unpacking code must be implemented inside vertex shader. /// - /// NOTE: + /// @remarks /// Must be called between begin/end. /// VertexDecl& add(Attrib::Enum _attrib, uint8_t _num, AttribType::Enum _type, bool _normalized = false, bool _asInt = false); @@ -453,14 +465,14 @@ namespace bgfx /// Returns current renderer backend API type. /// - /// NOTE: + /// @remarks /// Library must be initialized. /// RendererType::Enum getRendererType(); /// Returns renderer capabilities. /// - /// NOTE: + /// @remarks /// Library must be initialized. /// const Caps* getCaps(); @@ -479,16 +491,12 @@ namespace bgfx /// Set debug flags. /// /// @param _debug Available flags: - /// - /// BGFX_DEBUG_IFH - Infinitely fast hardware. When this flag is set + /// - `BGFX_DEBUG_IFH` - Infinitely fast hardware. When this flag is set /// all rendering calls will be skipped. It's useful when profiling /// to quickly assess bottleneck between CPU and GPU. - /// - /// BGFX_DEBUG_STATS - Display internal statistics. - /// - /// BGFX_DEBUG_TEXT - Display debug text. - /// - /// BGFX_DEBUG_WIREFRAME - Wireframe rendering. All rendering + /// - `BGFX_DEBUG_STATS` - Display internal statistics. + /// - `BGFX_DEBUG_TEXT` - Display debug text. + /// - `BGFX_DEBUG_WIREFRAME` - Wireframe rendering. All rendering /// primitives will be rendered as lines. /// void setDebug(uint32_t _debug); @@ -501,7 +509,7 @@ namespace bgfx /// Create static index buffer. /// - /// NOTE: + /// @remarks /// Only 16-bit index buffer is supported. /// IndexBufferHandle createIndexBuffer(const Memory* _mem); @@ -527,7 +535,7 @@ namespace bgfx /// /// @param _num Number of indices. /// - /// NOTE: + /// @remarks /// Only 16-bit index buffer is supported. /// DynamicIndexBufferHandle createDynamicIndexBuffer(uint32_t _num); @@ -536,7 +544,7 @@ namespace bgfx /// /// @param _mem Index buffer data. /// - /// NOTE: + /// @remarks /// Only 16-bit index buffer is supported. /// DynamicIndexBufferHandle createDynamicIndexBuffer(const Memory* _mem); @@ -610,7 +618,7 @@ namespace bgfx /// calls. /// @param _num Number of indices to allocate. /// - /// NOTE: + /// @remarks /// 1. You must call setIndexBuffer after alloc in order to avoid memory /// leak. /// 2. Only 16-bit index buffer is supported. @@ -625,7 +633,7 @@ namespace bgfx /// @param _num Number of vertices to allocate. /// @param _decl Vertex declaration. /// - /// NOTE: + /// @remarks /// You must call setVertexBuffer after alloc in order to avoid memory /// leak. /// @@ -635,14 +643,14 @@ namespace bgfx /// buffers. If both space requirements are satisfied function returns /// true. /// - /// NOTE: + /// @remarks /// Only 16-bit index buffer is supported. /// bool allocTransientBuffers(TransientVertexBuffer* _tvb, const VertexDecl& _decl, uint16_t _numVertices, TransientIndexBuffer* _tib, uint16_t _numIndices); /// Allocate instance data buffer. /// - /// NOTE: + /// @remarks /// You must call setInstanceDataBuffer after alloc in order to avoid /// memory leak. /// @@ -658,7 +666,7 @@ namespace bgfx /// @param _max Maximum capacity of array. /// @returns Number of uniforms used by shader. /// - /// NOTE: + /// @remarks /// Only non-predefined uniforms are returned. /// uint16_t getShaderUniforms(ShaderHandle _handle, UniformHandle* _uniforms = NULL, uint16_t _max = 0); @@ -686,18 +694,16 @@ namespace bgfx /// Create texture from memory buffer. /// - /// @param _mem DDS, KTX or PVR texture data. - /// @param _flags Default texture sampling mode is linear, and wrap mode + /// @param[in] _mem DDS, KTX or PVR texture data. + /// @param[in] _flags Default texture sampling mode is linear, and wrap mode /// is repeat. - /// - /// BGFX_TEXTURE_[U/V/W]_[MIRROR/CLAMP] - Mirror or clamp to edge wrap + /// - `BGFX_TEXTURE_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap /// mode. - /// - /// BGFX_TEXTURE_[MIN/MAG/MIP]_[POINT/ANISOTROPIC] - Point or anisotropic + /// - `BGFX_TEXTURE_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic /// sampling. /// - /// @param _skip Skip top level mips when parsing texture. - /// @param _info Returns parsed texture information. + /// @param[in] _skip Skip top level mips when parsing texture. + /// @param[out] _info When non-`NULL` is specified it returns parsed texture information. /// @returns Texture handle. /// TextureHandle createTexture(const Memory* _mem, uint32_t _flags = BGFX_TEXTURE_NONE, uint8_t _skip = 0, TextureInfo* _info = NULL); @@ -825,7 +831,7 @@ namespace bgfx /// @param _height Window back buffer height. /// @param _depthFormat Window back buffer depth format. /// - /// NOTE: + /// @remarks /// Frame buffer cannnot be used for sampling. /// FrameBufferHandle createFrameBuffer(void* _nwh, uint16_t _width, uint16_t _height, TextureFormat::Enum _depthFormat = TextureFormat::UnknownDepth); @@ -899,7 +905,7 @@ namespace bgfx /// @param _id View id. /// @param _name View name. /// - /// NOTE: + /// @remarks /// This is debug only feature. /// void setViewName(uint8_t _id, const char* _name); @@ -927,8 +933,8 @@ namespace bgfx /// Set view clear flags. /// /// @param _id View id. - /// @param _flags Clear flags. Use BGFX_CLEAR_NONE to remove any clear - /// operation. See: BGFX_CLEAR_*. + /// @param _flags Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear + /// operation. See: `BGFX_CLEAR_*`. /// @param _rgba Color clear value. /// @param _depth Depth clear value. /// @param _stencil Stencil clear value. @@ -940,8 +946,8 @@ namespace bgfx /// palette. /// /// @param _id View id. - /// @param _flags Clear flags. Use BGFX_CLEAR_NONE to remove any clear - /// operation. See: BGFX_CLEAR_*. + /// @param _flags Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear + /// operation. See: `BGFX_CLEAR_*`. /// @param _depth Depth clear value. /// @param _stencil Stencil clear value. /// @@ -954,12 +960,12 @@ namespace bgfx /// Set view frame buffer. /// /// @param _id View id. - /// @param _handle Frame buffer handle. Passing BGFX_INVALID_HANDLE as + /// @param _handle Frame buffer handle. Passing `BGFX_INVALID_HANDLE` as /// frame buffer handle will draw primitives from this view into /// default back buffer. /// - /// NOTE: - /// Not persistent after bgfx::reset call. + /// @remarks + /// Not persistent after `bgfx::reset` call. /// void setViewFrameBuffer(uint8_t _id, FrameBufferHandle _handle); @@ -973,25 +979,24 @@ namespace bgfx /// Set render states for draw primitive. /// /// @param _state State flags. Default state for primitive type is - /// triangles. See: BGFX_STATE_DEFAULT. + /// 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. /// - /// 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 NOTE 1: BGFX_STATE_BLEND_FUNC. - /// BGFX_STATE_BLEND_EQUATION_* - See NOTE 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 _rgba Sets blend factor used by `BGFX_STATE_BLEND_FACTOR` and + /// `BGFX_STATE_BLEND_INV_FACTOR` blend modes. /// - /// @param _rgba Sets blend factor used by BGFX_STATE_BLEND_FACTOR and - /// BGFX_STATE_BLEND_INV_FACTOR blend modes. - /// - /// NOTE: - /// 1. Use BGFX_STATE_ALPHA_REF, BGFX_STATE_POINT_SIZE and - /// BGFX_STATE_BLEND_FUNC macros to setup more complex states. - /// 2. BGFX_STATE_BLEND_EQUATION_ADD is set when no other blend + /// @remarks + /// 1. Use `BGFX_STATE_ALPHA_REF`, `BGFX_STATE_POINT_SIZE` and + /// `BGFX_STATE_BLEND_FUNC` macros to setup more complex states. + /// 2. `BGFX_STATE_BLEND_EQUATION_ADD` is set when no other blend /// equation is specified. /// void setState(uint64_t _state, uint32_t _rgba = 0); @@ -999,7 +1004,7 @@ namespace bgfx /// Set stencil test state. /// /// @param _fstencil Front stencil state. - /// @param _bstencil Back stencil state. If back is set to BGFX_STENCIL_NONE + /// @param _bstencil Back stencil state. If back is set to `BGFX_STENCIL_NONE` /// _fstencil is applied to both front and back facing primitives. /// void setStencil(uint32_t _fstencil, uint32_t _bstencil = BGFX_STENCIL_NONE); @@ -1039,6 +1044,12 @@ namespace bgfx /// void setTransform(uint32_t _cache, uint16_t _num = 1); + /// + void allocTransform(Transform* _transform, uint16_t _num); + + /// + void setTransform(const Transform* _transform, uint32_t _first, uint16_t _num); + /// Set shader uniform parameter for draw primitive. void setUniform(UniformHandle _handle, const void* _value, uint16_t _num = 1); @@ -1082,11 +1093,9 @@ namespace bgfx /// @param _handle Texture handle. /// @param _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 + /// - `BGFX_TEXTURE_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap /// mode. - /// - /// BGFX_TEXTURE_[MIN/MAG/MIP]_[POINT/ANISOTROPIC] - Point or anisotropic + /// - `BGFX_TEXTURE_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic /// sampling. /// /// @param _flags Texture sampler filtering flags. UINT32_MAX use the @@ -1102,11 +1111,9 @@ namespace bgfx /// @param _attachment Attachment index. /// @param _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 + /// - `BGFX_TEXTURE_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap /// mode. - /// - /// BGFX_TEXTURE_[MIN/MAG/MIP]_[POINT/ANISOTROPIC] - Point or anisotropic + /// - `BGFX_TEXTURE_[MIN/MAG/MIP]_[POINT/ANISOTROPIC]` - Point or anisotropic /// sampling. /// void setTexture(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment = 0, uint32_t _flags = UINT32_MAX); @@ -1135,7 +1142,7 @@ namespace bgfx /// /// @param _filePath Will be passed to CallbackI::screenShot callback. /// - /// NOTE: + /// @remarks /// CallbackI::screenShot must be implemented. /// void saveScreenShot(const char* _filePath); diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 0c5bf7a0..1816be94 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -2598,6 +2598,18 @@ again: s_ctx->setTransform(_cache, _num); } + void allocTransform(Transform* _transform, uint16_t _num) + { + BGFX_CHECK_MAIN_THREAD(); + s_ctx->allocTransform(_transform, _num); + } + + void setTransform(const Transform* _transform, uint32_t _first, uint16_t _num) + { + BGFX_CHECK_MAIN_THREAD(); + s_ctx->setTransform(_transform, _first, _num); + } + void setUniform(UniformHandle _handle, const void* _value, uint16_t _num) { BGFX_CHECK_MAIN_THREAD(); diff --git a/src/bgfx_p.h b/src/bgfx_p.h index d5dad8dc..ffe7432a 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -746,22 +746,38 @@ namespace bgfx m_num = 1; } + uint32_t reserve(uint16_t* _num) + { + BX_CHECK(m_num+_num < BGFX_CONFIG_MAX_MATRIX_CACHE, "Matrix cache overflow. %d (max: %d)", m_num+_num, BGFX_CONFIG_MAX_MATRIX_CACHE); + uint32_t num = bx::uint32_min(BGFX_CONFIG_MAX_MATRIX_CACHE-m_num, *_num); + uint32_t first = m_num; + m_num += num; + *_num = (uint16_t)num; + return first; + } + uint32_t add(const void* _mtx, uint16_t _num) { if (NULL != _mtx) { - BX_CHECK(m_num+_num < BGFX_CONFIG_MAX_MATRIX_CACHE, "Matrix cache overflow. %d (max: %d)", m_num+_num, BGFX_CONFIG_MAX_MATRIX_CACHE); - - uint32_t num = bx::uint32_min(BGFX_CONFIG_MAX_MATRIX_CACHE-m_num, _num); - uint32_t first = m_num; - memcpy(&m_cache[m_num], _mtx, sizeof(Matrix4)*num); - m_num += num; + uint32_t first = reserve(&_num); + memcpy(&m_cache[first], _mtx, sizeof(Matrix4)*_num); return first; } return 0; } + float* toPtr(uint32_t _cacheIdx) + { + return m_cache[_cacheIdx].un.val; + } + + uint32_t fromPtr(const void* _ptr) const + { + return uint32_t( (const Matrix4*)_ptr - m_cache); + } + Matrix4 m_cache[BGFX_CONFIG_MAX_MATRIX_CACHE]; uint32_t m_num; }; @@ -1226,7 +1242,7 @@ namespace bgfx uint32_t setTransform(const void* _mtx, uint16_t _num) { m_draw.m_matrix = m_matrixCache.add(_mtx, _num); - m_draw.m_num = _num; + m_draw.m_num = _num; return m_draw.m_matrix; } @@ -1234,53 +1250,66 @@ namespace bgfx void setTransform(uint32_t _cache, uint16_t _num) { m_draw.m_matrix = _cache; - m_draw.m_num = _num; + m_draw.m_num = _num; + } + + void allocTransform(Transform* _transform, uint16_t _num) + { + uint32_t first = m_matrixCache.reserve(&_num); + _transform->data = m_matrixCache.toPtr(first); + _transform->num = _num; + } + + void setTransform(const Transform* _transform, uint32_t _first, uint16_t _num) + { + m_draw.m_matrix = m_matrixCache.fromPtr(_transform->data) + _first; + m_draw.m_num = _num; } void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices) { - m_draw.m_startIndex = _firstIndex; - m_draw.m_numIndices = _numIndices; + m_draw.m_startIndex = _firstIndex; + m_draw.m_numIndices = _numIndices; m_draw.m_indexBuffer = _handle; } void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices) { m_draw.m_indexBuffer = _tib->handle; - m_draw.m_startIndex = _firstIndex; - m_draw.m_numIndices = _numIndices; + m_draw.m_startIndex = _firstIndex; + m_draw.m_numIndices = _numIndices; m_discard = 0 == _numIndices; } void setVertexBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices) { BX_CHECK(_handle.idx < BGFX_CONFIG_MAX_VERTEX_BUFFERS, "Invalid vertex buffer handle. %d (< %d)", _handle.idx, BGFX_CONFIG_MAX_VERTEX_BUFFERS); - m_draw.m_startVertex = _startVertex; - m_draw.m_numVertices = _numVertices; + m_draw.m_startVertex = _startVertex; + m_draw.m_numVertices = _numVertices; m_draw.m_vertexBuffer = _handle; } void setVertexBuffer(const DynamicVertexBuffer& _dvb, uint32_t _numVertices) { - m_draw.m_startVertex = _dvb.m_startVertex; - m_draw.m_numVertices = bx::uint32_min(_dvb.m_numVertices, _numVertices); + m_draw.m_startVertex = _dvb.m_startVertex; + m_draw.m_numVertices = bx::uint32_min(_dvb.m_numVertices, _numVertices); m_draw.m_vertexBuffer = _dvb.m_handle; - m_draw.m_vertexDecl = _dvb.m_decl; + m_draw.m_vertexDecl = _dvb.m_decl; } void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices) { - m_draw.m_startVertex = _startVertex; - m_draw.m_numVertices = bx::uint32_min(_tvb->size/_tvb->stride, _numVertices); + m_draw.m_startVertex = _startVertex; + m_draw.m_numVertices = bx::uint32_min(_tvb->size/_tvb->stride, _numVertices); m_draw.m_vertexBuffer = _tvb->handle; - m_draw.m_vertexDecl = _tvb->decl; + m_draw.m_vertexDecl = _tvb->decl; } void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num) { m_draw.m_instanceDataOffset = _idb->offset; m_draw.m_instanceDataStride = _idb->stride; - m_draw.m_numInstances = bx::uint16_min( (uint16_t)_idb->num, _num); + m_draw.m_numInstances = bx::uint16_min( (uint16_t)_idb->num, _num); m_draw.m_instanceDataBuffer = _idb->handle; BX_FREE(g_allocator, const_cast(_idb) ); } @@ -1294,8 +1323,8 @@ namespace bgfx void setTexture(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint32_t _flags) { Sampler& sampler = m_draw.m_sampler[_stage]; - sampler.m_idx = _handle.idx; - sampler.m_flags = (_flags&BGFX_SAMPLER_DEFAULT_FLAGS) ? BGFX_SAMPLER_DEFAULT_FLAGS : _flags; + sampler.m_idx = _handle.idx; + sampler.m_flags = (_flags&BGFX_SAMPLER_DEFAULT_FLAGS) ? BGFX_SAMPLER_DEFAULT_FLAGS : _flags; if (isValid(_sampler) && (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES) ) ) @@ -2756,6 +2785,16 @@ namespace bgfx m_submit->setTransform(_cache, _num); } + BGFX_API_FUNC(void allocTransform(Transform* _transform, uint16_t _num) ) + { + m_submit->allocTransform(_transform, _num); + } + + BGFX_API_FUNC(void setTransform(const Transform* _transform, uint32_t _first, uint16_t _num) ) + { + m_submit->setTransform(_transform, _first, _num); + } + BGFX_API_FUNC(void setUniform(UniformHandle _handle, const void* _value, uint16_t _num) ) { UniformRef& uniform = m_uniformRef[_handle.idx];