diff --git a/include/bgfx.h b/include/bgfx.h index c9b1d538..8c288591 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -243,6 +243,26 @@ namespace bgfx }; }; + struct UniformType + { + enum Enum + { + Uniform1i, + Uniform1f, + End, + + Uniform1iv, + Uniform1fv, + Uniform2fv, + Uniform3fv, + Uniform4fv, + Uniform3x3fv, + Uniform4x4fv, + + Count + }; + }; + static const uint16_t invalidHandle = UINT16_MAX; BGFX_HANDLE(DynamicIndexBufferHandle); @@ -257,6 +277,11 @@ namespace bgfx BGFX_HANDLE(VertexDeclHandle); BGFX_HANDLE(VertexShaderHandle); + typedef void (*FatalFn)(Fatal::Enum _code, const char* _str); + typedef void* (*ReallocFn)(void* _ptr, size_t _size); + typedef void (*FreeFn)(void* _ptr); + typedef void (*CacheFn)(uint64_t _id, bool _store, void* _data, uint32_t& _length); + struct Memory { uint8_t* data; @@ -291,31 +316,14 @@ namespace bgfx VertexBufferHandle handle; }; - struct UniformType + struct TextureInfo { - enum Enum - { - Uniform1i, - Uniform1f, - End, - - Uniform1iv, - Uniform1fv, - Uniform2fv, - Uniform3fv, - Uniform4fv, - Uniform3x3fv, - Uniform4x4fv, - - Count - }; + TextureFormat::Enum format; + uint16_t width; + uint16_t height; + uint16_t depth; }; - typedef void (*FatalFn)(Fatal::Enum _code, const char* _str); - typedef void* (*ReallocFn)(void* _ptr, size_t _size); - typedef void (*FreeFn)(void* _ptr); - typedef void (*CacheFn)(uint64_t _id, bool _store, void* _data, uint32_t& _length); - struct VertexDecl { /// Start VertexDecl. @@ -432,13 +440,13 @@ namespace bgfx /// void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle); - /// + /// Returns true if internal transient index buffer has enough space. bool checkAvailTransientIndexBuffer(uint16_t _num); /// const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num); - /// + /// Returns true if internal transient vertex buffer has enough space. bool checkAvailTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl); /// @@ -447,26 +455,28 @@ namespace bgfx /// const InstanceDataBuffer* allocInstanceDataBuffer(uint16_t _num, uint16_t _stride); - /// + /// Create vertex shader from memory buffer. VertexShaderHandle createVertexShader(const Memory* _mem); - /// + /// Destroy vertex shader. Once program is created with vertex shader + /// it is safe to destroy vertex shader. void destroyVertexShader(VertexShaderHandle _handle); - /// + /// Create fragment shader from memory buffer. FragmentShaderHandle createFragmentShader(const Memory* _mem); - /// + /// Destroy fragment shader. Once program is created with fragment shader + /// it is safe to destroy fragment shader. void destroyFragmentShader(FragmentShaderHandle _handle); - /// + /// Create program with vertex and fragment shaders. ProgramHandle createProgram(VertexShaderHandle _vsh, FragmentShaderHandle _fsh); - /// + /// Destroy program. void destroyProgram(ProgramHandle _handle); - /// - TextureHandle createTexture(const Memory* _mem, uint32_t _flags = BGFX_TEXTURE_NONE, uint16_t* _width = NULL, uint16_t* _height = NULL); + /// Create texture from memory buffer. + TextureHandle createTexture(const Memory* _mem, uint32_t _flags = BGFX_TEXTURE_NONE, TextureInfo* _info = NULL); /// TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags = BGFX_TEXTURE_NONE, const Memory* _mem = NULL); diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 01990dc8..ec38f8ef 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -979,79 +979,79 @@ namespace bgfx s_ctx.destroyProgram(_handle); } - TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint16_t* _width, uint16_t* _height) + TextureHandle createTexture(const Memory* _mem, uint32_t _flags, TextureInfo* _info) { BX_CHECK(NULL != _mem, "_mem can't be NULL"); - return s_ctx.createTexture(_mem, _flags, _width, _height); + return s_ctx.createTexture(_mem, _flags, _info); } TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) { - uint32_t size = sizeof(uint32_t)+sizeof(TextureInfo); + uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate); const bgfx::Memory* mem = alloc(size); StreamWrite stream(mem->data, mem->size); uint32_t magic = BGFX_MAGIC; stream.write(magic); - TextureInfo ti; - ti.m_flags = _flags; - ti.m_width = _width; - ti.m_height = _height; - ti.m_depth = 0; - ti.m_numMips = _numMips; - ti.m_type = uint8_t(_format); - ti.m_cubeMap = false; - ti.m_mem = _mem; - stream.write(ti); + TextureCreate tc; + tc.m_flags = _flags; + tc.m_width = _width; + tc.m_height = _height; + tc.m_depth = 0; + tc.m_numMips = _numMips; + tc.m_type = uint8_t(_format); + tc.m_cubeMap = false; + tc.m_mem = _mem; + stream.write(tc); - return s_ctx.createTexture(mem, _flags, NULL, NULL); + return s_ctx.createTexture(mem, _flags, NULL); } TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) { - uint32_t size = sizeof(uint32_t)+sizeof(TextureInfo); + uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate); const bgfx::Memory* mem = alloc(size); StreamWrite stream(mem->data, mem->size); uint32_t magic = BGFX_MAGIC; stream.write(magic); - TextureInfo ti; - ti.m_flags = _flags; - ti.m_width = _width; - ti.m_height = _height; - ti.m_depth = _depth; - ti.m_numMips = _numMips; - ti.m_type = uint8_t(_format); - ti.m_cubeMap = false; - ti.m_mem = _mem; - stream.write(ti); + TextureCreate tc; + tc.m_flags = _flags; + tc.m_width = _width; + tc.m_height = _height; + tc.m_depth = _depth; + tc.m_numMips = _numMips; + tc.m_type = uint8_t(_format); + tc.m_cubeMap = false; + tc.m_mem = _mem; + stream.write(tc); - return s_ctx.createTexture(mem, _flags, NULL, NULL); + return s_ctx.createTexture(mem, _flags, NULL); } TextureHandle createTextureCube(uint16_t _sides, uint16_t _width, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) { - uint32_t size = sizeof(uint32_t)+sizeof(TextureInfo); + uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate); const bgfx::Memory* mem = alloc(size); StreamWrite stream(mem->data, mem->size); uint32_t magic = BGFX_MAGIC; stream.write(magic); - TextureInfo ti; - ti.m_flags = _flags; - ti.m_width = _width; - ti.m_sides = _sides; - ti.m_depth = 0; - ti.m_numMips = _numMips; - ti.m_type = uint8_t(_format); - ti.m_cubeMap = true; - ti.m_mem = _mem; - stream.write(ti); + TextureCreate tc; + tc.m_flags = _flags; + tc.m_width = _width; + tc.m_sides = _sides; + tc.m_depth = 0; + tc.m_numMips = _numMips; + tc.m_type = uint8_t(_format); + tc.m_cubeMap = true; + tc.m_mem = _mem; + stream.write(tc); - return s_ctx.createTexture(mem, _flags, NULL, NULL); + return s_ctx.createTexture(mem, _flags, NULL); } void destroyTexture(TextureHandle _handle) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 01c3c097..0008c99d 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -163,7 +163,7 @@ namespace bgfx uint16_t m_height; }; - struct TextureInfo + struct TextureCreate { uint32_t m_flags; uint16_t m_width; @@ -2014,29 +2014,24 @@ namespace bgfx fragmentShaderDecRef(m_programRef[_handle.idx].m_fsh); } - TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint16_t* _width, uint16_t* _height) + TextureHandle createTexture(const Memory* _mem, uint32_t _flags, TextureInfo* _info = NULL) { - if (NULL != _width - || NULL != _height) + if (NULL != _info) { - int width = 0; - int height = 0; - Dds dds; if (parseDds(dds, _mem) ) { - width = dds.m_width; - height = dds.m_height; + _info->format = dds.m_type; + _info->width = (uint16_t)dds.m_width; + _info->height = (uint16_t)dds.m_height; + _info->depth = (uint16_t)dds.m_depth; } - - if (NULL != _width) + else { - *_width = (uint16_t)width; - } - - if (NULL != _height) - { - *_height = (uint16_t)height; + _info->format = TextureFormat::Unknown; + _info->width = 0; + _info->height = 0; + _info->depth = 0; } } diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 9674f35e..fe41e1d8 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1362,40 +1362,42 @@ namespace bgfx if (BGFX_MAGIC == magic) { - TextureInfo ti; - stream.read(ti); + TextureCreate tc; + stream.read(tc); D3D11_TEXTURE2D_DESC desc; - desc.Width = ti.m_width; - desc.Height = ti.m_height; - desc.MipLevels = ti.m_numMips; + desc.Width = tc.m_width; + desc.Height = tc.m_height; + desc.MipLevels = tc.m_numMips; desc.ArraySize = 1; - desc.Format = s_textureFormat[ti.m_type].m_fmt; + desc.Format = s_textureFormat[tc.m_type].m_fmt; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; - m_numMips = ti.m_numMips; + m_numMips = tc.m_numMips; - if (NULL != ti.m_mem) + if (NULL != tc.m_mem) { desc.Usage = D3D11_USAGE_IMMUTABLE; - D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(ti.m_numMips*sizeof(D3D11_SUBRESOURCE_DATA) ); - uint32_t bpp = s_textureFormat[ti.m_type].m_bpp; - uint8_t* data = ti.m_mem->data; + D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(tc.m_numMips*sizeof(D3D11_SUBRESOURCE_DATA) ); + uint32_t bpp = s_textureFormat[tc.m_type].m_bpp; + uint8_t* data = tc.m_mem->data; - for (uint8_t side = 0, numSides = ti.m_cubeMap ? 6 : 1; side < numSides; ++side) + for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side) { - uint32_t width = ti.m_width; - uint32_t height = ti.m_height; + uint32_t width = tc.m_width; + uint32_t height = tc.m_height; + uint32_t depth = tc.m_depth; - for (uint32_t lod = 0, num = ti.m_numMips; lod < num; ++lod) + for (uint32_t lod = 0, num = tc.m_numMips; lod < num; ++lod) { - width = uint32_max(width, 1); - height = uint32_max(height, 1); + width = uint32_max(1, width); + height = uint32_max(1, height); + depth = uint32_max(1, depth); srd[lod].pSysMem = data; srd[lod].SysMemPitch = width*bpp; @@ -1405,12 +1407,13 @@ namespace bgfx width >>= 1; height >>= 1; + depth >>= 1; } } DX_CHECK(s_renderCtx.m_device->CreateTexture2D(&desc, srd, &m_texture2d) ); - release(ti.m_mem); + release(tc.m_mem); } else { @@ -1422,7 +1425,7 @@ namespace bgfx D3D11_SHADER_RESOURCE_VIEW_DESC srv; memset(&srv, 0, sizeof(srv) ); srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srv.Texture2D.MipLevels = ti.m_numMips; + srv.Texture2D.MipLevels = tc.m_numMips; DX_CHECK(s_renderCtx.m_device->CreateShaderResourceView(m_ptr, &srv, &m_srv) ); } else diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 10f76353..9fe05bea 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -1285,36 +1285,38 @@ namespace bgfx if (BGFX_MAGIC == magic) { - TextureInfo ti; - stream.read(ti); + TextureCreate tc; + stream.read(tc); - if (ti.m_cubeMap) + if (tc.m_cubeMap) { - createCubeTexture(ti.m_width, ti.m_numMips, s_textureFormat[ti.m_type].m_fmt); + createCubeTexture(tc.m_width, tc.m_numMips, s_textureFormat[tc.m_type].m_fmt); } - else if (ti.m_depth > 1) + else if (tc.m_depth > 1) { - createVolumeTexture(ti.m_width, ti.m_height, ti.m_depth, ti.m_numMips, s_textureFormat[ti.m_type].m_fmt); + createVolumeTexture(tc.m_width, tc.m_height, tc.m_depth, tc.m_numMips, s_textureFormat[tc.m_type].m_fmt); } else { - createTexture(ti.m_width, ti.m_height, ti.m_numMips, s_textureFormat[ti.m_type].m_fmt); + createTexture(tc.m_width, tc.m_height, tc.m_numMips, s_textureFormat[tc.m_type].m_fmt); } - if (NULL != ti.m_mem) + if (NULL != tc.m_mem) { - uint32_t bpp = s_textureFormat[ti.m_type].m_bpp; - uint8_t* data = ti.m_mem->data; + uint32_t bpp = s_textureFormat[tc.m_type].m_bpp; + uint8_t* data = tc.m_mem->data; - for (uint8_t side = 0, numSides = ti.m_cubeMap ? 6 : 1; side < numSides; ++side) + for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side) { - uint32_t width = ti.m_width; - uint32_t height = ti.m_height; + uint32_t width = tc.m_width; + uint32_t height = tc.m_height; + uint32_t depth = tc.m_depth; - for (uint32_t lod = 0, num = ti.m_numMips; lod < num; ++lod) + for (uint32_t lod = 0, num = tc.m_numMips; lod < num; ++lod) { - width = uint32_max(width, 1); - height = uint32_max(height, 1); + width = uint32_max(1, width); + height = uint32_max(1, height); + depth = uint32_max(1, depth); uint32_t pitch; uint32_t slicePitch; @@ -1326,10 +1328,11 @@ namespace bgfx width >>= 1; height >>= 1; + depth >>= 1; } } - release(ti.m_mem); + release(tc.m_mem); } } else diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 8ce173b8..e2e2cd71 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -1158,6 +1158,72 @@ namespace bgfx } } + static void texImage(GLenum _target, GLint _level, GLint _internalFormat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLenum _format, GLenum _type, const GLvoid* _pixels) + { +#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3 + if (_target == GL_TEXTURE_3D) + { + GL_CHECK(glTexImage3D(_target + , _level + , _internalFormat + , _width + , _height + , _depth + , _border + , _format + , _type + , _pixels + ) ); + } + else +#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3 + { + BX_UNUSED(_depth); + GL_CHECK(glTexImage2D(_target + , _level + , _internalFormat + , _width + , _height + , _border + , _format + , _type + , _pixels + ) ); + } + } + + static void compressedTexImage(GLenum _target, GLint _level, GLenum _internalformat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLsizei _imageSize, const GLvoid* _data) + { +#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3 + if (_target == GL_TEXTURE_3D) + { + GL_CHECK(glCompressedTexImage3D(_target + , _level + , _internalformat + , _width + , _height + , _depth + , _border + , _imageSize + , _data + ) ); + } + else +#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3 + { + BX_UNUSED(_depth); + GL_CHECK(glCompressedTexImage2D(_target + , _level + , _internalformat + , _width + , _height + , _border + , _imageSize + , _data + ) ); + } + } + void Texture::create(const Memory* _mem, uint32_t _flags) { Dds dds; @@ -1171,12 +1237,12 @@ namespace bgfx { m_target = GL_TEXTURE_CUBE_MAP; } -#if BGFX_CONFIG_RENDERER_OPENGL +#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3 else if (dds.m_depth > 1) { m_target = GL_TEXTURE_3D; } -#endif // BGFX_CONFIG_RENDERER_OPENGL +#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3 else { m_target = GL_TEXTURE_2D; @@ -1250,35 +1316,17 @@ namespace bgfx } } -#if BGFX_CONFIG_RENDERER_OPENGL - if (target == GL_TEXTURE_3D) - { - GL_CHECK(glTexImage3D(target - , lod - , internalFmt - , width - , height - , depth - , 0 - , m_fmt - , m_type - , bits - ) ); - } - else -#endif // BGFX_CONFIG_RENDERER_OPENGL - { - GL_CHECK(glTexImage2D(target+side - , lod - , internalFmt - , width - , height - , 0 - , m_fmt - , m_type - , bits - ) ); - } + texImage(target+side + , lod + , internalFmt + , width + , height + , depth + , 0 + , m_fmt + , m_type + , bits + ); } width >>= 1; @@ -1306,33 +1354,16 @@ namespace bgfx Mip mip; if (getRawImageData(dds, side, ii, _mem, mip) ) { -#if BGFX_CONFIG_RENDERER_OPENGL - if (m_target == GL_TEXTURE_3D) - { - GL_CHECK(glCompressedTexImage3D(target - , ii - , internalFmt - , width - , height - , depth - , 0 - , mip.m_size - , mip.m_data - ) ); - } - else -#endif // BGFX_CONFIG_RENDERER_OPENGL - { - GL_CHECK(glCompressedTexImage2D(target+side - , ii - , internalFmt - , width - , height - , 0 - , mip.m_size - , mip.m_data - ) ); - } + compressedTexImage(target+side + , ii + , internalFmt + , width + , height + , depth + , 0 + , mip.m_size + , mip.m_data + ); } width >>= 1; @@ -1341,15 +1372,9 @@ namespace bgfx } } } - } else { - m_target = GL_TEXTURE_2D; - GL_CHECK(glGenTextures(1, &m_id) ); - BX_CHECK(0 != m_id, "Failed to generate texture id."); - GL_CHECK(glBindTexture(m_target, m_id) ); - StreamRead stream(_mem->data, _mem->size); uint32_t magic; @@ -1357,37 +1382,63 @@ namespace bgfx if (BGFX_MAGIC == magic) { - TextureInfo ti; - stream.read(ti); + TextureCreate tc; + stream.read(tc); - const TextureFormatInfo& tfi = s_textureFormat[ti.m_type]; + if (tc.m_cubeMap) + { + m_target = GL_TEXTURE_CUBE_MAP; + } + else if (tc.m_depth > 1) + { + m_target = GL_TEXTURE_3D; + } + else + { + m_target = GL_TEXTURE_2D; + } + + GL_CHECK(glGenTextures(1, &m_id) ); + BX_CHECK(0 != m_id, "Failed to generate texture id."); + GL_CHECK(glBindTexture(m_target, m_id) ); + + const TextureFormatInfo& tfi = s_textureFormat[tc.m_type]; GLenum internalFmt = tfi.m_internalFmt; m_fmt = tfi.m_fmt; m_type = tfi.m_type; - uint32_t bpp = s_textureFormat[ti.m_type].m_bpp; - uint8_t* data = NULL != ti.m_mem ? ti.m_mem->data : NULL; - - for (uint8_t side = 0, numSides = ti.m_cubeMap ? 6 : 1; side < numSides; ++side) + GLenum target = m_target; + if (tc.m_cubeMap) { - uint32_t width = ti.m_width; - uint32_t height = ti.m_height; + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; + } - for (uint32_t lod = 0, num = ti.m_numMips; lod < num; ++lod) + uint32_t bpp = s_textureFormat[tc.m_type].m_bpp; + uint8_t* data = NULL != tc.m_mem ? tc.m_mem->data : NULL; + + for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side) + { + uint32_t width = tc.m_width; + uint32_t height = tc.m_height; + uint32_t depth = tc.m_depth; + + for (uint32_t lod = 0, num = tc.m_numMips; lod < num; ++lod) { width = uint32_max(width, 1); height = uint32_max(height, 1); + depth = uint32_max(1, depth); - GL_CHECK(glTexImage2D(m_target - , lod - , internalFmt - , width - , height - , 0 - , m_fmt - , m_type - , data - ) ); + texImage(target+side + , lod + , internalFmt + , width + , height + , depth + , 0 + , m_fmt + , m_type + , data + ); if (NULL != data) { @@ -1396,12 +1447,13 @@ namespace bgfx width >>= 1; height >>= 1; + depth >>= 1; } } - if (NULL != ti.m_mem) + if (NULL != tc.m_mem) { - release(ti.m_mem); + release(tc.m_mem); } } else diff --git a/src/renderer_null.cpp b/src/renderer_null.cpp index f6ec85e6..883755e8 100644 --- a/src/renderer_null.cpp +++ b/src/renderer_null.cpp @@ -114,12 +114,12 @@ namespace bgfx if (BGFX_MAGIC == magic) { - TextureInfo ti; - stream.read(ti); + TextureCreate tc; + stream.read(tc); - if (NULL != ti.m_mem) + if (NULL != tc.m_mem) { - release(ti.m_mem); + release(tc.m_mem); } } }