From c01a93e29d4871be0e29961949ee5f05f5f3c673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Mon, 13 Apr 2015 18:39:38 -0700 Subject: [PATCH] Added support for automatic texture scaling by backbuffer ratio on backbuffer resize. --- examples/09-hdr/hdr.cpp | 9 +---- include/bgfx.h | 38 +++++++++++++++---- src/bgfx.cpp | 81 +++++++++++++++++++++++++++++++++++------ src/bgfx_p.h | 38 ++++++++++++++++++- src/renderer_d3d11.cpp | 31 +++++++++++++++- src/renderer_d3d9.cpp | 7 ++++ src/renderer_gl.cpp | 29 +++++++++++++++ src/renderer_null.cpp | 4 ++ 8 files changed, 208 insertions(+), 29 deletions(-) diff --git a/examples/09-hdr/hdr.cpp b/examples/09-hdr/hdr.cpp index c8dbfea15..f8ccb29aa 100644 --- a/examples/09-hdr/hdr.cpp +++ b/examples/09-hdr/hdr.cpp @@ -216,10 +216,10 @@ int _main_(int /*_argc*/, char** /*_argv*/) lum[4] = bgfx::createFrameBuffer( 1, 1, bgfx::TextureFormat::BGRA8); bgfx::FrameBufferHandle bright; - bright = bgfx::createFrameBuffer(width/2, height/2, bgfx::TextureFormat::BGRA8); + bright = bgfx::createFrameBuffer(bgfx::BackbufferRatio::Half, bgfx::TextureFormat::BGRA8); bgfx::FrameBufferHandle blur; - blur = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8); + blur = bgfx::createFrameBuffer(bgfx::BackbufferRatio::Eighth, bgfx::TextureFormat::BGRA8); // Imgui. imguiCreate(); @@ -256,15 +256,10 @@ int _main_(int /*_argc*/, char** /*_argv*/) uint32_t msaa = (reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT; bgfx::destroyFrameBuffer(fbh); - bgfx::destroyFrameBuffer(bright); - bgfx::destroyFrameBuffer(blur); fbtextures[0] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, ( (msaa+1)<resizeTexture(handle, width, height); + } + break; + case CommandBuffer::DestroyTexture: { TextureHandle handle; @@ -2412,10 +2427,28 @@ again: { BGFX_CHECK_MAIN_THREAD(); BX_CHECK(NULL != _mem, "_mem can't be NULL"); - return s_ctx->createTexture(_mem, _flags, _skip, _info); + return s_ctx->createTexture(_mem, _flags, _skip, _info, BackbufferRatio::None); } - TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) + void getTextureSizeFromRatio(BackbufferRatio::Enum _ratio, uint16_t& _width, uint16_t& _height) + { + switch (_ratio) + { + case BackbufferRatio::Half: _width /= 2; _height /= 2; break; + case BackbufferRatio::Quarter: _width /= 4; _height /= 4; break; + case BackbufferRatio::Eighth: _width /= 8; _height /= 8; break; + case BackbufferRatio::Sixteenth: _width /= 16; _height /= 16; break; + case BackbufferRatio::Double: _width *= 2; _height *= 2; break; + + default: + break; + } + + _width = bx::uint16_max(1, _width); + _height = bx::uint16_max(1, _height); + } + + TextureHandle createTexture2D(BackbufferRatio::Enum _ratio, uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) { BGFX_CHECK_MAIN_THREAD(); @@ -2440,19 +2473,36 @@ again: uint32_t magic = BGFX_CHUNK_MAGIC_TEX; bx::write(&writer, magic); + if (BackbufferRatio::None != _ratio) + { + _width = uint16_t(s_ctx->m_frame->m_resolution.m_width); + _height = uint16_t(s_ctx->m_frame->m_resolution.m_height); + getTextureSizeFromRatio(_ratio, _width, _height); + } + TextureCreate tc; - tc.m_flags = _flags; - tc.m_width = _width; - tc.m_height = _height; - tc.m_sides = 0; - tc.m_depth = 0; + tc.m_flags = _flags; + tc.m_width = _width; + tc.m_height = _height; + tc.m_sides = 0; + tc.m_depth = 0; tc.m_numMips = _numMips; - tc.m_format = uint8_t(_format); + tc.m_format = uint8_t(_format); tc.m_cubeMap = false; - tc.m_mem = _mem; + tc.m_mem = _mem; bx::write(&writer, tc); - return s_ctx->createTexture(mem, _flags, 0, NULL); + return s_ctx->createTexture(mem, _flags, 0, NULL, _ratio); + } + + TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) + { + return createTexture2D(BackbufferRatio::None, _width, _height, _numMips, _format, _flags, _mem); + } + + TextureHandle createTexture2D(BackbufferRatio::Enum _ratio, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags) + { + return createTexture2D(_ratio, 0, 0, _numMips, _format, _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) @@ -2493,7 +2543,7 @@ again: tc.m_mem = _mem; bx::write(&writer, tc); - return s_ctx->createTexture(mem, _flags, 0, NULL); + return s_ctx->createTexture(mem, _flags, 0, NULL, BackbufferRatio::None); } TextureHandle createTextureCube(uint16_t _size, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem) @@ -2533,7 +2583,7 @@ again: tc.m_mem = _mem; bx::write(&writer, tc); - return s_ctx->createTexture(mem, _flags, 0, NULL); + return s_ctx->createTexture(mem, _flags, 0, NULL, BackbufferRatio::None); } void destroyTexture(TextureHandle _handle) @@ -2596,6 +2646,13 @@ again: return createFrameBuffer(1, &th, true); } + FrameBufferHandle createFrameBuffer(BackbufferRatio::Enum _ratio, TextureFormat::Enum _format, uint32_t _textureFlags) + { + _textureFlags |= _textureFlags&BGFX_TEXTURE_RT_MSAA_MASK ? 0 : BGFX_TEXTURE_RT; + TextureHandle th = createTexture2D(_ratio, 1, _format, _textureFlags); + return createFrameBuffer(1, &th, true); + } + FrameBufferHandle createFrameBuffer(uint8_t _num, TextureHandle* _handles, bool _destroyTextures) { BGFX_CHECK_MAIN_THREAD(); diff --git a/src/bgfx_p.h b/src/bgfx_p.h index a1d0dbd0e..5c804ad6e 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -305,6 +305,7 @@ namespace bgfx bool isGraphicsDebuggerPresent(); void release(const Memory* _mem); const char* getAttribName(Attrib::Enum _attr); + void getTextureSizeFromRatio(BackbufferRatio::Enum _ratio, uint16_t& _width, uint16_t& _height); inline uint32_t castfu(float _value) { @@ -568,6 +569,7 @@ namespace bgfx CreateProgram, CreateTexture, UpdateTexture, + ResizeTexture, CreateFrameBuffer, CreateUniform, UpdateViewName, @@ -1849,6 +1851,7 @@ namespace bgfx virtual void updateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip) = 0; virtual void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) = 0; virtual void updateTextureEnd() = 0; + virtual void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) = 0; virtual void destroyTexture(TextureHandle _handle) = 0; virtual void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const TextureHandle* _textureHandles) = 0; virtual void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat) = 0; @@ -1925,6 +1928,17 @@ namespace bgfx m_resolution.m_flags = _flags; memset(m_fb, 0xff, sizeof(m_fb) ); + + for (uint16_t ii = 0, num = m_textureHandle.getNumHandles(); ii < num; ++ii) + { + uint16_t textureIdx = m_textureHandle.getHandleAt(ii); + const TextureRef& textureRef = m_textureRef[textureIdx]; + if (BackbufferRatio::None != textureRef.m_bbRatio) + { + TextureHandle handle = { textureIdx }; + resizeTexture(handle, uint16_t(m_resolution.m_width), uint16_t(m_resolution.m_height) ); + } + } } BGFX_API_FUNC(void setDebug(uint32_t _debug) ) @@ -2723,7 +2737,7 @@ namespace bgfx } } - BGFX_API_FUNC(TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info) ) + BGFX_API_FUNC(TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info, BackbufferRatio::Enum _ratio) ) { TextureInfo ti; if (NULL == _info) @@ -2761,6 +2775,7 @@ namespace bgfx { TextureRef& ref = m_textureRef[handle.idx]; ref.m_refCount = 1; + ref.m_bbRatio = uint8_t(_ratio); ref.m_format = uint8_t(_info->format); CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateTexture); @@ -2786,6 +2801,26 @@ namespace bgfx textureDecRef(_handle); } + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) + { + const TextureRef& textureRef = m_textureRef[_handle.idx]; + BX_CHECK(BackbufferRatio::None != textureRef.m_bbRatio, ""); + + getTextureSizeFromRatio(BackbufferRatio::Enum(textureRef.m_bbRatio), _width, _height); + + BX_TRACE("Resize %3d: %4dx%d %s" + , _handle.idx + , _width + , _height + , getName(TextureFormat::Enum(textureRef.m_format) ) + ); + + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::ResizeTexture); + cmdbuf.write(_handle); + cmdbuf.write(_width); + cmdbuf.write(_height); + } + void textureIncRef(TextureHandle _handle) { TextureRef& ref = m_textureRef[_handle.idx]; @@ -3437,6 +3472,7 @@ namespace bgfx struct TextureRef { int16_t m_refCount; + uint8_t m_bbRatio; uint8_t m_format; }; diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 4429e1e85..25f268d20 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -978,6 +978,35 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { } + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE + { + TextureD3D11& texture = m_textures[_handle.idx]; + + uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate); + const Memory* mem = alloc(size); + + bx::StaticMemoryBlockWriter writer(mem->data, mem->size); + uint32_t magic = BGFX_CHUNK_MAGIC_TEX; + bx::write(&writer, magic); + + TextureCreate tc; + tc.m_flags = texture.m_flags; + tc.m_width = _width; + tc.m_height = _height; + tc.m_sides = 0; + tc.m_depth = 0; + tc.m_numMips = 1; + tc.m_format = texture.m_requestedFormat; + tc.m_cubeMap = false; + tc.m_mem = NULL; + bx::write(&writer, tc); + + texture.destroy(); + texture.create(mem, tc.m_flags, 0); + + release(mem); + } + void destroyTexture(TextureHandle _handle) BX_OVERRIDE { m_textures[_handle.idx].destroy(); @@ -2462,7 +2491,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; BX_CHECK(m_dynamic, "Must be dynamic!"); -#if 1 +#if 0 BX_UNUSED(_discard); ID3D11Device* device = s_renderD3D11->m_device; diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index f32f0d80b..9bce8f52c 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -774,6 +774,13 @@ namespace bgfx { namespace d3d9 m_updateTexture = NULL; } + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE + { + TextureD3D9& texture = m_textures[_handle.idx]; + texture.m_width = _width; + texture.m_height = _height; + } + void destroyTexture(TextureHandle _handle) BX_OVERRIDE { m_textures[_handle.idx].destroy(); diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 46350aa31..27afd476e 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -1717,6 +1717,35 @@ namespace bgfx { namespace gl { } + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height) BX_OVERRIDE + { + TextureGL& texture = m_textures[_handle.idx]; + + uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate); + const Memory* mem = alloc(size); + + bx::StaticMemoryBlockWriter writer(mem->data, mem->size); + uint32_t magic = BGFX_CHUNK_MAGIC_TEX; + bx::write(&writer, magic); + + TextureCreate tc; + tc.m_flags = texture.m_flags; + tc.m_width = _width; + tc.m_height = _height; + tc.m_sides = 0; + tc.m_depth = 0; + tc.m_numMips = 1; + tc.m_format = texture.m_requestedFormat; + tc.m_cubeMap = false; + tc.m_mem = NULL; + bx::write(&writer, tc); + + texture.destroy(); + texture.create(mem, tc.m_flags, 0); + + release(mem); + } + void destroyTexture(TextureHandle _handle) BX_OVERRIDE { m_textures[_handle.idx].destroy(); diff --git a/src/renderer_null.cpp b/src/renderer_null.cpp index 76cd0fadb..0ad831923 100644 --- a/src/renderer_null.cpp +++ b/src/renderer_null.cpp @@ -113,6 +113,10 @@ namespace bgfx { namespace noop { } + void resizeTexture(TextureHandle /*_handle*/, uint16_t /*_width*/, uint16_t /*_height*/) BX_OVERRIDE + { + } + void destroyTexture(TextureHandle /*_handle*/) BX_OVERRIDE { }