Added support for automatic texture scaling by backbuffer ratio on backbuffer resize.

This commit is contained in:
Branimir Karadžić 2015-04-13 18:39:38 -07:00
parent 6878b8de29
commit c01a93e29d
8 changed files with 208 additions and 29 deletions

View File

@ -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)<<BGFX_TEXTURE_RT_MSAA_SHIFT)|BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP);
fbtextures[1] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY|( (msaa+1)<<BGFX_TEXTURE_RT_MSAA_SHIFT) );
fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
bright = bgfx::createFrameBuffer(width/2, height/2, bgfx::TextureFormat::BGRA8);
blur = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8);
}
imguiBeginFrame(mouseState.m_mx

View File

@ -189,6 +189,20 @@ namespace bgfx
};
};
struct BackbufferRatio
{
enum Enum
{
None,
Equal,
Half,
Quarter,
Eighth,
Sixteenth,
Double,
};
};
static const uint16_t invalidHandle = UINT16_MAX;
BGFX_HANDLE(DynamicIndexBufferHandle);
@ -318,10 +332,9 @@ namespace bgfx
uint16_t maxTextureSize; ///< Maximum texture size.
uint16_t maxViews; ///< Maximum views.
uint8_t maxFBAttachments; ///< Maximum frame buffer attachments.
uint8_t numGPUs; ///<
uint16_t vendorId; ///<
uint16_t deviceId; ///<
uint8_t numGPUs; ///< Number of enumerated GPUs.
uint16_t vendorId; ///< Selected GPU vendor id.
uint16_t deviceId; ///< Selected GPU device id.
struct GPU
{
@ -329,7 +342,7 @@ namespace bgfx
uint16_t deviceId;
};
GPU gpu[4]; ///<
GPU gpu[4]; ///< Enumerated GPUs.
/// Supported texture formats.
/// - `BGFX_CAPS_FORMAT_TEXTURE_NONE` - not supported
@ -549,10 +562,10 @@ namespace bgfx
///
void shutdown();
/// Reset graphic settings.
/// Reset graphic settings and back-buffer size.
///
/// @param _width Main window width.
/// @param _height Main window height.
/// @param _width Back-buffer width.
/// @param _height Back-buffer height.
/// @param _flags
/// - `BGFX_RESET_NONE` - No reset flags.
/// - `BGFX_RESET_FULLSCREEN` - Not supported yet.
@ -560,6 +573,9 @@ namespace bgfx
/// - `BGFX_RESET_VSYNC` - Enable V-Sync.
/// - `BGFX_RESET_CAPTURE` - Begin screen capture.
///
/// @attention This call doesn't actually change window size, it just
/// resizes back-buffer. Windowing code has to change window size.
///
/// @attention C99 equivalent is `bgfx_reset`.
///
void reset(uint32_t _width, uint32_t _height, uint32_t _flags = BGFX_RESET_NONE);
@ -917,6 +933,9 @@ namespace bgfx
///
TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags = BGFX_TEXTURE_NONE, const Memory* _mem = NULL);
///
TextureHandle createTexture2D(BackbufferRatio::Enum _ratio, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags = BGFX_TEXTURE_NONE);
/// Create 3D texture.
///
/// @param _width
@ -1013,6 +1032,9 @@ namespace bgfx
///
FrameBufferHandle createFrameBuffer(uint16_t _width, uint16_t _height, TextureFormat::Enum _format, uint32_t _textureFlags = BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP);
///
FrameBufferHandle createFrameBuffer(BackbufferRatio::Enum _ratio, TextureFormat::Enum _format, uint32_t _textureFlags = BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP);
/// Create frame buffer.
///
/// @param _num Number of texture attachments.

View File

@ -1830,6 +1830,21 @@ again:
}
break;
case CommandBuffer::ResizeTexture:
{
TextureHandle handle;
_cmdbuf.read(handle);
uint16_t width;
_cmdbuf.read(width);
uint16_t height;
_cmdbuf.read(height);
m_renderCtx->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();

View File

@ -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;
};

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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
{
}