Added multiple windows support.

This commit is contained in:
Branimir Karadžić 2014-09-07 17:17:38 -07:00
parent 50cbdbec3c
commit 2c03cf4927
19 changed files with 633 additions and 162 deletions

View file

@ -815,6 +815,9 @@ namespace bgfx
///
FrameBufferHandle createFrameBuffer(uint8_t _num, TextureHandle* _handles, bool _destroyTextures = false);
/// Create frame buffer.
FrameBufferHandle createFrameBuffer(void* _nwh, uint16_t _width, uint16_t _height, TextureFormat::Enum _depthFormat = TextureFormat::UnknownDepth);
/// Destroy frame buffer.
void destroyFrameBuffer(FrameBufferHandle _handle);
@ -971,6 +974,9 @@ namespace bgfx
/// frame buffer handle will draw primitives from this view into
/// default back buffer.
///
/// NOTE:
/// Not persistent after bgfx::reset call.
///
void setViewFrameBuffer(uint8_t _id, FrameBufferHandle _handle);
/// Set view frame buffer for multiple views.
@ -980,6 +986,9 @@ namespace bgfx
/// frame buffer handle will draw primitives from this view into
/// default back buffer.
///
/// NOTE:
/// Not persistent after bgfx::reset call.
///
void setViewFrameBufferMask(uint32_t _viewMask, FrameBufferHandle _handle);
/// Set view view and projection matrices, all draw primitives in this

View file

@ -699,12 +699,13 @@ namespace bgfx
BX_WARN(invalidHandle != m_key.m_program, "Program with invalid handle");
if (invalidHandle != m_key.m_program)
{
m_key.m_depth = _depth;
m_key.m_view = _id;
m_key.m_seq = s_ctx->m_seq[_id] & s_ctx->m_seqMask[_id];
m_key.m_depth = _depth;
m_key.m_view = _id;
m_key.m_seq = s_ctx->m_seq[_id] & s_ctx->m_seqMask[_id];
s_ctx->m_seq[_id]++;
uint64_t key = m_key.encodeDraw();
m_sortKeys[m_num] = key;
m_sortKeys[m_num] = key;
m_sortValues[m_num] = m_numRenderItems;
++m_num;
@ -749,11 +750,12 @@ namespace bgfx
viewMask >>= ntz;
id += ntz;
m_key.m_view = id;
m_key.m_seq = s_ctx->m_seq[id] & s_ctx->m_seqMask[id];
m_key.m_view = id;
m_key.m_seq = s_ctx->m_seq[id] & s_ctx->m_seqMask[id];
s_ctx->m_seq[id]++;
uint64_t key = m_key.encodeDraw();
m_sortKeys[m_num] = key;
m_sortKeys[m_num] = key;
m_sortValues[m_num] = m_numRenderItems;
++m_num;
}
@ -794,12 +796,13 @@ namespace bgfx
m_key.m_program = _handle.idx;
if (invalidHandle != m_key.m_program)
{
m_key.m_depth = 0;
m_key.m_view = _id;
m_key.m_seq = s_ctx->m_seq[_id] & s_ctx->m_seqMask[_id];
m_key.m_depth = 0;
m_key.m_view = _id;
m_key.m_seq = s_ctx->m_seq[_id] & s_ctx->m_seqMask[_id];
s_ctx->m_seq[_id]++;
uint64_t key = m_key.encodeCompute();
m_sortKeys[m_num] = key;
m_sortKeys[m_num] = key;
m_sortValues[m_num] = m_numRenderItems;
++m_num;
@ -1094,7 +1097,6 @@ namespace bgfx
CHECK_HANDLE_LEAK(m_textureHandle);
CHECK_HANDLE_LEAK(m_frameBufferHandle);
CHECK_HANDLE_LEAK(m_uniformHandle);
#undef CHECK_HANDLE_LEAK
}
}
@ -1781,16 +1783,38 @@ again:
FrameBufferHandle handle;
_cmdbuf.read(handle);
uint8_t num;
_cmdbuf.read(num);
bool window;
_cmdbuf.read(window);
TextureHandle textureHandles[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
for (uint32_t ii = 0; ii < num; ++ii)
if (window)
{
_cmdbuf.read(textureHandles[ii]);
}
void* nwh;
_cmdbuf.read(nwh);
m_renderCtx->createFrameBuffer(handle, num, textureHandles);
uint16_t width;
_cmdbuf.read(width);
uint16_t height;
_cmdbuf.read(height);
TextureFormat::Enum depthFormat;
_cmdbuf.read(depthFormat);
m_renderCtx->createFrameBuffer(handle, nwh, width, height, depthFormat);
}
else
{
uint8_t num;
_cmdbuf.read(num);
TextureHandle textureHandles[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
for (uint32_t ii = 0; ii < num; ++ii)
{
_cmdbuf.read(textureHandles[ii]);
}
m_renderCtx->createFrameBuffer(handle, num, textureHandles);
}
}
break;
@ -2479,6 +2503,12 @@ again:
return handle;
}
FrameBufferHandle createFrameBuffer(void* _nwh, uint16_t _width, uint16_t _height, TextureFormat::Enum _depthFormat)
{
BGFX_CHECK_MAIN_THREAD();
return s_ctx->createFrameBuffer(_nwh, _width, _height, _depthFormat);
}
void destroyFrameBuffer(FrameBufferHandle _handle)
{
BGFX_CHECK_MAIN_THREAD();

View file

@ -640,6 +640,10 @@ namespace bgfx
};
#define SORT_KEY_RENDER_DRAW UINT64_C(0x0000000800000000)
BX_STATIC_ASSERT(BGFX_CONFIG_MAX_VIEWS <= 32);
BX_STATIC_ASSERT( (BGFX_CONFIG_MAX_PROGRAMS & (BGFX_CONFIG_MAX_PROGRAMS-1) ) == 0); // must be power of 2
struct SortKey
{
uint64_t encodeDraw()
@ -1422,14 +1426,14 @@ namespace bgfx
void resetFreeHandles()
{
m_numFreeIndexBufferHandles = 0;
m_numFreeVertexDeclHandles = 0;
m_numFreeIndexBufferHandles = 0;
m_numFreeVertexDeclHandles = 0;
m_numFreeVertexBufferHandles = 0;
m_numFreeShaderHandles = 0;
m_numFreeProgramHandles = 0;
m_numFreeTextureHandles = 0;
m_numFreeFrameBufferHandles = 0;
m_numFreeUniformHandles = 0;
m_numFreeShaderHandles = 0;
m_numFreeProgramHandles = 0;
m_numFreeTextureHandles = 0;
m_numFreeFrameBufferHandles = 0;
m_numFreeUniformHandles = 0;
}
SortKey m_key;
@ -1479,6 +1483,7 @@ namespace bgfx
uint16_t m_numFreeTextureHandles;
uint16_t m_numFreeFrameBufferHandles;
uint16_t m_numFreeUniformHandles;
uint16_t m_numFreeWindowHandles;
IndexBufferHandle m_freeIndexBufferHandle[BGFX_CONFIG_MAX_INDEX_BUFFERS];
VertexDeclHandle m_freeVertexDeclHandle[BGFX_CONFIG_MAX_VERTEX_DECLS];
@ -1696,6 +1701,7 @@ namespace bgfx
virtual void updateTextureEnd() = 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;
virtual void destroyFrameBuffer(FrameBufferHandle _handle) = 0;
virtual void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) = 0;
virtual void destroyUniform(UniformHandle _handle) = 0;
@ -2464,23 +2470,25 @@ namespace bgfx
BGFX_API_FUNC(FrameBufferHandle createFrameBuffer(uint8_t _num, TextureHandle* _handles) )
{
FrameBufferHandle handle = { m_frameBufferHandle.alloc() };
BX_WARN(isValid(handle), "Failed to allocate render target handle.");
BX_WARN(isValid(handle), "Failed to allocate frame buffer handle.");
if (isValid(handle) )
{
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateFrameBuffer);
cmdbuf.write(handle);
cmdbuf.write(false);
cmdbuf.write(_num);
FrameBufferRef& ref = m_frameBufferRef[handle.idx];
memset(ref.m_th, 0xff, sizeof(ref.m_th) );
ref.m_window = false;
memset(ref.un.m_th, 0xff, sizeof(ref.un.m_th) );
for (uint32_t ii = 0; ii < _num; ++ii)
{
TextureHandle handle = _handles[ii];
cmdbuf.write(handle);
ref.m_th[ii] = handle;
ref.un.m_th[ii] = handle;
textureIncRef(handle);
}
}
@ -2488,6 +2496,29 @@ namespace bgfx
return handle;
}
BGFX_API_FUNC(FrameBufferHandle createFrameBuffer(void* _nwh, uint16_t _width, uint16_t _height, TextureFormat::Enum _depthFormat) )
{
FrameBufferHandle handle = { m_frameBufferHandle.alloc() };
BX_WARN(isValid(handle), "Failed to allocate frame buffer handle.");
if (isValid(handle) )
{
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateFrameBuffer);
cmdbuf.write(handle);
cmdbuf.write(true);
cmdbuf.write(_nwh);
cmdbuf.write(_width);
cmdbuf.write(_height);
cmdbuf.write(_depthFormat);
FrameBufferRef& ref = m_frameBufferRef[handle.idx];
ref.m_window = true;
ref.un.m_nwh = _nwh;
}
return handle;
}
BGFX_API_FUNC(void destroyFrameBuffer(FrameBufferHandle _handle) )
{
CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::DestroyFrameBuffer);
@ -2495,12 +2526,15 @@ namespace bgfx
m_submit->free(_handle);
FrameBufferRef& ref = m_frameBufferRef[_handle.idx];
for (uint32_t ii = 0; ii < BX_COUNTOF(ref.m_th); ++ii)
if (!ref.m_window)
{
TextureHandle th = ref.m_th[ii];
if (isValid(th) )
for (uint32_t ii = 0; ii < BX_COUNTOF(ref.un.m_th); ++ii)
{
textureDecRef(th);
TextureHandle th = ref.un.m_th[ii];
if (isValid(th) )
{
textureDecRef(th);
}
}
}
}
@ -2614,7 +2648,7 @@ namespace bgfx
Rect& rect = m_rect[_id];
rect.m_x = _x;
rect.m_y = _y;
rect.m_width = bx::uint16_max(_width, 1);
rect.m_width = bx::uint16_max(_width, 1);
rect.m_height = bx::uint16_max(_height, 1);
}
@ -2634,7 +2668,7 @@ namespace bgfx
Rect& scissor = m_scissor[_id];
scissor.m_x = _x;
scissor.m_y = _y;
scissor.m_width = _width;
scissor.m_width = _width;
scissor.m_height = _height;
}
@ -2850,7 +2884,9 @@ namespace bgfx
TextureHandle textureHandle = BGFX_INVALID_HANDLE;
if (isValid(_handle) )
{
textureHandle = m_frameBufferRef[_handle.idx].m_th[_attachment];
const FrameBufferRef& ref = m_frameBufferRef[_handle.idx];
BX_CHECK(!ref.m_window, "Can't sample window frame buffer.");
textureHandle = ref.un.m_th[_attachment];
BX_CHECK(isValid(textureHandle), "Frame buffer texture %d is invalid.", _attachment);
}
@ -2878,7 +2914,9 @@ namespace bgfx
TextureHandle textureHandle = BGFX_INVALID_HANDLE;
if (isValid(_handle) )
{
textureHandle = m_frameBufferRef[_handle.idx].m_th[_attachment];
const FrameBufferRef& ref = m_frameBufferRef[_handle.idx];
BX_CHECK(!ref.m_window, "Can't sample window frame buffer.");
textureHandle = ref.un.m_th[_attachment];
BX_CHECK(isValid(textureHandle), "Frame buffer texture %d is invalid.", _attachment);
}
@ -3014,7 +3052,12 @@ namespace bgfx
struct FrameBufferRef
{
TextureHandle m_th[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
union un
{
TextureHandle m_th[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
void* m_nwh;
} un;
bool m_window;
};
typedef stl::unordered_map<stl::string, UniformHandle> UniformHashMap;

View file

@ -10,6 +10,8 @@
namespace bgfx
{
struct SwapChainGL;
struct GlContext
{
GlContext()
@ -21,8 +23,19 @@ namespace bgfx
void destroy();
void resize(uint32_t _width, uint32_t _height, bool _vsync);
void swap();
SwapChainGL* createSwapChain(void* _nwh);
void destorySwapChain(SwapChainGL* _swapChain);
void swap(SwapChainGL* _swapChain = NULL);
void makeCurrent(SwapChainGL* _swapChain = NULL);
void import();
GLuint getFbo()
{
return m_fbo;
}
bool isValid() const
{
return 0 != m_context;

View file

@ -237,12 +237,28 @@ EGL_IMPORT
eglSwapInterval(m_display, _vsync ? 1 : 0);
}
void GlContext::swap()
SwapChainGL* GlContext::createSwapChain(void* /*_nwh*/)
{
BX_CHECK(false, "Shouldn't be called!");
return NULL;
}
void GlContext::destorySwapChain(SwapChainGL* /*_swapChain*/)
{
BX_CHECK(false, "Shouldn't be called!");
}
void GlContext::swap(SwapChainGL* _swapChain)
{
BX_CHECK(NULL == _swapChain, "Shouldn't be called!"); BX_UNUSED(_swapChain);
eglMakeCurrent(m_display, m_surface, m_surface, m_context);
eglSwapBuffers(m_display, m_surface);
}
void GlContext::makeCurrent(SwapChainGL* /*_swapChain*/)
{
}
void GlContext::import()
{
BX_TRACE("Import:");

View file

@ -12,6 +12,8 @@
namespace bgfx
{
struct SwapChainGL;
struct GlContext
{
GlContext()
@ -24,7 +26,12 @@ namespace bgfx
void create(uint32_t _width, uint32_t _height);
void destroy();
void resize(uint32_t _width, uint32_t _height, bool _vsync);
void swap();
SwapChainGL* createSwapChain(void* _nwh);
void destorySwapChain(SwapChainGL* _swapChain);
void swap(SwapChainGL* _swapChain = NULL);
void makeCurrent(SwapChainGL* _swapChain = NULL);
void import();
bool isValid() const

View file

@ -212,11 +212,27 @@ namespace bgfx
}
}
void GlContext::swap()
SwapChainGL* GlContext::createSwapChain(void* /*_nwh*/)
{
BX_CHECK(false, "Shouldn't be called!");
return NULL;
}
void GlContext::destorySwapChain(SwapChainGL* /*_swapChain*/)
{
BX_CHECK(false, "Shouldn't be called!");
}
void GlContext::swap(SwapChainGL* _swapChain)
{
BX_CHECK(NULL == _swapChain, "Shouldn't be called!"); BX_UNUSED(_swapChain);
glXSwapBuffers(s_display, s_window);
}
void GlContext::makeCurrent(SwapChainGL* /*_swapChain*/)
{
}
void GlContext::import()
{
# define GL_EXTENSION(_optional, _proto, _func, _import) \

View file

@ -13,6 +13,8 @@
namespace bgfx
{
struct SwapChainGL;
struct GlContext
{
GlContext()
@ -23,7 +25,12 @@ namespace bgfx
void create(uint32_t _width, uint32_t _height);
void destroy();
void resize(uint32_t _width, uint32_t _height, bool _vsync);
void swap();
SwapChainGL* createSwapChain(void* _nwh);
void destorySwapChain(SwapChainGL* _swapChain);
void swap(SwapChainGL* _swapChain = NULL);
void makeCurrent(SwapChainGL* _swapChain = NULL);
void import();
bool isValid() const

View file

@ -158,11 +158,26 @@ namespace bgfx
s_ppapi.resize(_width, _height, _vsync);
}
void GlContext::swap()
SwapChainGL* GlContext::createSwapChain(void* /*_nwh*/)
{
BX_CHECK(false, "Shouldn't be called!");
return NULL;
}
void GlContext::destorySwapChain(SwapChainGL* /*_swapChain*/)
{
BX_CHECK(false, "Shouldn't be called!");
}
void GlContext::swap(SwapChainGL* /*_swapChain*/)
{
s_ppapi.swap();
}
void GlContext::makeCurrent(SwapChainGL* /*_swapChain*/)
{
}
void GlContext::import()
{
}

View file

@ -15,6 +15,8 @@
namespace bgfx
{
struct SwapChainGL;
struct GlContext
{
GlContext()
@ -24,7 +26,12 @@ namespace bgfx
void create(uint32_t _width, uint32_t _height);
void destroy();
void resize(uint32_t _width, uint32_t _height, bool _vsync);
void swap();
SwapChainGL* createSwapChain(void* _nwh);
void destorySwapChain(SwapChainGL* _swapChain);
void swap(SwapChainGL* _swapChain = NULL);
void makeCurrent(SwapChainGL* _swapChain = NULL);
void import();
bool isValid() const;
};

View file

@ -24,6 +24,36 @@ namespace bgfx
# define GL_IMPORT(_optional, _proto, _func, _import) _proto _func
# include "glimports.h"
struct SwapChainGL
{
SwapChainGL(void* _nwh)
: m_hwnd( (HWND)_nwh)
{
m_hdc = GetDC(m_hwnd);
}
~SwapChainGL()
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_context);
ReleaseDC(m_hwnd, m_hdc);
}
void makeCurrent()
{
wglMakeCurrent(m_hdc, m_context);
}
void swapBuffers()
{
SwapBuffers(m_hdc);
}
HWND m_hwnd;
HDC m_hdc;
HGLRC m_context;
};
static HGLRC createContext(HDC _hdc)
{
PIXELFORMATDESCRIPTOR pfd;
@ -121,10 +151,10 @@ namespace bgfx
HGLRC context = createContext(hdc);
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
if (NULL != wglGetExtensionsStringARB)
{
@ -151,11 +181,10 @@ namespace bgfx
};
int result;
int pixelFormat;
uint32_t numFormats = 0;
do
{
result = wglChoosePixelFormatARB(m_hdc, attrs, NULL, 1, &pixelFormat, &numFormats);
result = wglChoosePixelFormatARB(m_hdc, attrs, NULL, 1, &m_pixelFormat, &numFormats);
if (0 == result
|| 0 == numFormats)
{
@ -165,8 +194,7 @@ namespace bgfx
} while (0 == numFormats);
PIXELFORMATDESCRIPTOR pfd;
DescribePixelFormat(m_hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
DescribePixelFormat(m_hdc, m_pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &m_pfd);
BX_TRACE("Pixel format:\n"
"\tiPixelType %d\n"
@ -174,14 +202,14 @@ namespace bgfx
"\tcAlphaBits %d\n"
"\tcDepthBits %d\n"
"\tcStencilBits %d\n"
, pfd.iPixelType
, pfd.cColorBits
, pfd.cAlphaBits
, pfd.cDepthBits
, pfd.cStencilBits
, m_pfd.iPixelType
, m_pfd.cColorBits
, m_pfd.cAlphaBits
, m_pfd.cDepthBits
, m_pfd.cStencilBits
);
result = SetPixelFormat(m_hdc, pixelFormat, &pfd);
result = SetPixelFormat(m_hdc, m_pixelFormat, &m_pfd);
// When window is created by SDL and SDL_WINDOW_OPENGL is set SetPixelFormat
// will fail. Just warn and continue. In case it failed for some other reason
// create context will fail and it will error out there.
@ -213,6 +241,9 @@ namespace bgfx
m_context = wglCreateContextAttribsARB(m_hdc, 0, contextAttrs);
}
BGFX_FATAL(NULL != m_context, Fatal::UnableToInitialize, "Failed to create context 0x%08x.", GetLastError() );
BX_STATIC_ASSERT(sizeof(contextAttrs) == sizeof(m_contextAttrs) );
memcpy(m_contextAttrs, contextAttrs, sizeof(contextAttrs) );
}
wglMakeCurrent(NULL, NULL);
@ -261,12 +292,49 @@ namespace bgfx
}
}
void GlContext::swap()
SwapChainGL* GlContext::createSwapChain(void* _nwh)
{
if (NULL != g_bgfxHwnd)
SwapChainGL* swapChain = BX_NEW(g_allocator, SwapChainGL)(_nwh);
int result = SetPixelFormat(swapChain->m_hdc, m_pixelFormat, &m_pfd);
BX_WARN(result, "SetPixelFormat failed (last err: 0x%08x)!", GetLastError() );
swapChain->m_context = wglCreateContextAttribsARB(swapChain->m_hdc, m_context, m_contextAttrs);
BX_CHECK(NULL != swapChain->m_context, "Create swap chain failed: %x", glGetError() );
return swapChain;
}
void GlContext::destorySwapChain(SwapChainGL* _swapChain)
{
BX_DELETE(g_allocator, _swapChain);
}
void GlContext::makeCurrent(SwapChainGL* _swapChain)
{
if (NULL == _swapChain)
{
wglMakeCurrent(m_hdc, m_context);
SwapBuffers(m_hdc);
}
else
{
_swapChain->makeCurrent();
}
}
void GlContext::swap(SwapChainGL* _swapChain)
{
if (NULL == _swapChain)
{
if (NULL != g_bgfxHwnd)
{
wglMakeCurrent(m_hdc, m_context);
SwapBuffers(m_hdc);
}
}
else
{
_swapChain->makeCurrent();
_swapChain->swapBuffers();
}
}

View file

@ -15,7 +15,7 @@ namespace bgfx
typedef PROC (APIENTRYP PFNWGLGETPROCADDRESSPROC) (LPCSTR lpszProc);
typedef BOOL (APIENTRYP PFNWGLMAKECURRENTPROC) (HDC hdc, HGLRC hglrc);
typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTPROC) (HDC hdc);
typedef BOOL (APIENTRYP PFNWGLDELETECONTEXTPROC) (HGLRC hglrc);
typedef BOOL (APIENTRYP PFNWGLDELETECONTEXTPROC) (HGLRC hglrc);
//
typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);
typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
@ -56,6 +56,8 @@ typedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum z
extern PFNWGLCREATECONTEXTPROC wglCreateContext;
extern PFNWGLDELETECONTEXTPROC wglDeleteContext;
struct SwapChainGL;
struct GlContext
{
GlContext()
@ -68,7 +70,12 @@ typedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum z
void create(uint32_t _width, uint32_t _height);
void destroy();
void resize(uint32_t _width, uint32_t _height, bool _vsync);
void swap();
SwapChainGL* createSwapChain(void* _nwh);
void destorySwapChain(SwapChainGL* _swapChain);
void swap(SwapChainGL* _swapChain = NULL);
void makeCurrent(SwapChainGL* _swapChain = NULL);
void import();
bool isValid() const
@ -76,6 +83,9 @@ typedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum z
return NULL != m_context;
}
int32_t m_contextAttrs[9];
int m_pixelFormat;
PIXELFORMATDESCRIPTOR m_pfd;
void* m_opengl32dll;
HGLRC m_context;
HDC m_hdc;

View file

@ -515,7 +515,7 @@ namespace bgfx
};
memset(&m_scd, 0, sizeof(m_scd) );
m_scd.BufferDesc.Width = BGFX_DEFAULT_WIDTH;
m_scd.BufferDesc.Width = BGFX_DEFAULT_WIDTH;
m_scd.BufferDesc.Height = BGFX_DEFAULT_HEIGHT;
m_scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_scd.BufferDesc.RefreshRate.Numerator = 60;
@ -573,6 +573,8 @@ namespace bgfx
);
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");
m_numWindows = 1;
if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
{
ID3D11InfoQueue* infoQueue;
@ -792,9 +794,26 @@ namespace bgfx
m_frameBuffers[_handle.idx].create(_num, _textureHandles);
}
void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat) BX_OVERRIDE
{
uint16_t denseIdx = m_numWindows++;
m_windows[denseIdx] = _handle;
m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _depthFormat);
}
void destroyFrameBuffer(FrameBufferHandle _handle) BX_OVERRIDE
{
m_frameBuffers[_handle.idx].destroy();
uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy();
if (UINT16_MAX != denseIdx)
{
--m_numWindows;
if (m_numWindows > 1)
{
FrameBufferHandle handle = m_windows[m_numWindows];
m_windows[denseIdx] = handle;
m_frameBuffers[handle.idx].m_denseIdx = denseIdx;
}
}
}
void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) BX_OVERRIDE
@ -1013,6 +1032,10 @@ namespace bgfx
if (NULL != m_swapChain)
{
uint32_t syncInterval = !!(m_flags & BGFX_RESET_VSYNC);
for (uint32_t ii = 1, num = m_numWindows; ii < num; ++ii)
{
DX_CHECK(m_frameBuffers[m_windows[ii].idx].m_swapChain->Present(syncInterval, 0) );
}
DX_CHECK(m_swapChain->Present(syncInterval, 0) );
}
}
@ -1820,7 +1843,11 @@ namespace bgfx
IDXGIAdapter* m_adapter;
DXGI_ADAPTER_DESC m_adapterDesc;
IDXGIFactory* m_factory;
IDXGISwapChain* m_swapChain;
uint16_t m_numWindows;
FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
ID3D11Device* m_device;
ID3D11DeviceContext* m_deviceCtx;
ID3D11RenderTargetView* m_backBufferColor;
@ -2442,7 +2469,8 @@ namespace bgfx
{
m_rtv[ii] = NULL;
}
m_dsv = NULL;
m_dsv = NULL;
m_swapChain = NULL;
m_num = 0;
for (uint32_t ii = 0; ii < _num; ++ii)
@ -2475,7 +2503,34 @@ namespace bgfx
}
}
void FrameBufferD3D11::destroy()
void FrameBufferD3D11::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat)
{
BX_UNUSED(_depthFormat);
DXGI_SWAP_CHAIN_DESC scd;
memcpy(&scd, &s_renderD3D11->m_scd, sizeof(DXGI_SWAP_CHAIN_DESC) );
scd.BufferDesc.Width = _width;
scd.BufferDesc.Height = _height;
scd.OutputWindow = (HWND)_nwh;
HRESULT hr;
hr = s_renderD3D11->m_factory->CreateSwapChain(s_renderD3D11->m_device
, &scd
, &m_swapChain
);
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");
ID3D11Resource* ptr;
DX_CHECK(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&ptr) );
DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(ptr, NULL, &m_rtv[0]) );
DX_RELEASE(ptr, 0);
m_srv[0] = NULL;
m_dsv = NULL;
m_denseIdx = _denseIdx;
m_num = 1;
}
uint16_t FrameBufferD3D11::destroy()
{
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
{
@ -2484,8 +2539,14 @@ namespace bgfx
}
DX_RELEASE(m_dsv, 0);
DX_RELEASE(m_swapChain, 0);
m_num = 0;
uint16_t denseIdx = m_denseIdx;
m_denseIdx = UINT16_MAX;
return denseIdx;
}
void FrameBufferD3D11::resolve()

View file

@ -273,18 +273,22 @@ namespace bgfx
struct FrameBufferD3D11
{
FrameBufferD3D11()
: m_num(0)
: m_denseIdx(UINT16_MAX)
, m_num(0)
{
}
void create(uint8_t _num, const TextureHandle* _handles);
void destroy();
void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
uint16_t destroy();
void resolve();
void clear(const Clear& _clear, const float _palette[][4]);
ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
ID3D11DepthStencilView* m_dsv;
IDXGISwapChain* m_swapChain;
uint16_t m_denseIdx;
uint8_t m_num;
};

View file

@ -259,8 +259,6 @@ namespace bgfx
RendererContextD3D9()
: m_d3d9(NULL)
, m_device(NULL)
, m_backBufferColor(NULL)
, m_backBufferDepthStencil(NULL)
, m_captureTexture(NULL)
, m_captureSurface(NULL)
, m_captureResolve(NULL)
@ -292,7 +290,7 @@ namespace bgfx
m_params.FullScreen_RefreshRateInHz = 0;
m_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
m_params.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_params.hDeviceWindow = g_bgfxHwnd;
m_params.hDeviceWindow = NULL;
m_params.Windowed = true;
RECT rect;
@ -304,9 +302,9 @@ namespace bgfx
BGFX_FATAL(NULL != m_d3d9dll, Fatal::UnableToInitialize, "Failed to load d3d9.dll.");
#if BGFX_CONFIG_DEBUG_PIX
m_D3DPERF_SetMarker = (D3DPERF_SetMarkerFunc)bx::dlsym(m_d3d9dll, "D3DPERF_SetMarker");
m_D3DPERF_SetMarker = (D3DPERF_SetMarkerFunc )bx::dlsym(m_d3d9dll, "D3DPERF_SetMarker");
m_D3DPERF_BeginEvent = (D3DPERF_BeginEventFunc)bx::dlsym(m_d3d9dll, "D3DPERF_BeginEvent");
m_D3DPERF_EndEvent = (D3DPERF_EndEventFunc)bx::dlsym(m_d3d9dll, "D3DPERF_EndEvent");
m_D3DPERF_EndEvent = (D3DPERF_EndEventFunc )bx::dlsym(m_d3d9dll, "D3DPERF_EndEvent");
BX_CHECK(NULL != m_D3DPERF_SetMarker
&& NULL != m_D3DPERF_BeginEvent
@ -373,9 +371,9 @@ namespace bgfx
uint32_t behaviorFlags[] =
{
D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE|D3DCREATE_FPU_PRESERVE,
D3DCREATE_MIXED_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_FPU_PRESERVE,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE | D3DCREATE_PUREDEVICE,
D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
};
for (uint32_t ii = 0; ii < BX_COUNTOF(behaviorFlags) && NULL == m_device; ++ii)
@ -402,6 +400,8 @@ namespace bgfx
BGFX_FATAL(m_device, Fatal::UnableToInitialize, "Unable to create Direct3D9 device.");
m_numWindows = 1;
#if BGFX_CONFIG_RENDERER_DIRECT3D9EX
if (NULL != m_d3d9ex)
{
@ -711,9 +711,26 @@ namespace bgfx
m_frameBuffers[_handle.idx].create(_num, _textureHandles);
}
void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat) BX_OVERRIDE
{
uint16_t denseIdx = m_numWindows++;
m_windows[denseIdx] = _handle;
m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _depthFormat);
}
void destroyFrameBuffer(FrameBufferHandle _handle) BX_OVERRIDE
{
m_frameBuffers[_handle.idx].destroy();
uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy();
if (UINT16_MAX != denseIdx)
{
--m_numWindows;
if (m_numWindows > 1)
{
FrameBufferHandle handle = m_windows[m_numWindows];
m_windows[denseIdx] = handle;
m_frameBuffers[handle.idx].m_denseIdx = denseIdx;
}
}
}
void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) BX_OVERRIDE
@ -902,9 +919,9 @@ namespace bgfx
void updateResolution(const Resolution& _resolution)
{
if (m_params.BackBufferWidth != _resolution.m_width
|| m_params.BackBufferHeight != _resolution.m_height
|| m_flags != _resolution.m_flags)
if (m_params.BackBufferWidth != _resolution.m_width
|| m_params.BackBufferHeight != _resolution.m_height
|| m_flags != _resolution.m_flags)
{
m_flags = _resolution.m_flags;
@ -921,7 +938,7 @@ namespace bgfx
m_params.BackBufferFormat = dm.Format;
#endif // BX_PLATFORM_WINDOWS
m_params.BackBufferWidth = _resolution.m_width;
m_params.BackBufferWidth = _resolution.m_width;
m_params.BackBufferHeight = _resolution.m_height;
m_params.FullScreen_RefreshRateInHz = BGFX_RESET_FULLSCREEN == (m_flags&BGFX_RESET_FULLSCREEN_MASK) ? 60 : 0;
m_params.PresentationInterval = !!(m_flags&BGFX_RESET_VSYNC) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
@ -929,7 +946,7 @@ namespace bgfx
updateMsaa();
Msaa& msaa = s_msaa[(m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
m_params.MultiSampleType = msaa.m_type;
m_params.MultiSampleType = msaa.m_type;
m_params.MultiSampleQuality = msaa.m_quality;
m_resolution = _resolution;
@ -1033,30 +1050,42 @@ namespace bgfx
}
#endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
HRESULT hr;
hr = m_device->Present(NULL, NULL, NULL, NULL);
for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)
{
HRESULT hr;
if (0 == ii)
{
hr = m_swapChain->Present(NULL, NULL, g_bgfxHwnd, NULL, 0);
}
else
{
hr = m_frameBuffers[m_windows[ii].idx].present();
}
#if BX_PLATFORM_WINDOWS
if (isLost(hr) )
{
do
if (isLost(hr) )
{
do
do
{
do
{
hr = m_device->TestCooperativeLevel();
}
while (D3DERR_DEVICENOTRESET != hr);
reset();
hr = m_device->TestCooperativeLevel();
}
while (D3DERR_DEVICENOTRESET != hr);
while (FAILED(hr) );
reset();
hr = m_device->TestCooperativeLevel();
break;
}
else if (FAILED(hr) )
{
BX_TRACE("Present failed with err 0x%08x.", hr);
}
while (FAILED(hr) );
}
else if (FAILED(hr) )
{
BX_TRACE("Present failed with err 0x%08x.", hr);
}
#endif // BX_PLATFORM_
}
}
}
@ -1082,6 +1111,7 @@ namespace bgfx
DX_RELEASE(m_backBufferColor, 0);
DX_RELEASE(m_backBufferDepthStencil, 0);
DX_RELEASE(m_swapChain, 0);
capturePreReset();
@ -1108,7 +1138,8 @@ namespace bgfx
void postReset()
{
DX_CHECK(m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_backBufferColor) );
DX_CHECK(m_device->GetSwapChain(0, &m_swapChain) );
DX_CHECK(m_swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &m_backBufferColor) );
DX_CHECK(m_device->GetDepthStencilSurface(&m_backBufferDepthStencil) );
capturePostReset();
@ -1179,9 +1210,9 @@ namespace bgfx
{
if (m_flags&BGFX_RESET_CAPTURE)
{
uint32_t width = m_params.BackBufferWidth;
uint32_t width = m_params.BackBufferWidth;
uint32_t height = m_params.BackBufferHeight;
D3DFORMAT fmt = m_params.BackBufferFormat;
D3DFORMAT fmt = m_params.BackBufferFormat;
DX_CHECK(m_device->CreateTexture(width
, height
@ -1567,6 +1598,10 @@ namespace bgfx
IDirect3DDevice9* m_device;
D3DPOOL m_pool;
IDirect3DSwapChain9* m_swapChain;
uint16_t m_numWindows;
FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
IDirect3DSurface9* m_backBufferColor;
IDirect3DSurface9* m_backBufferDepthStencil;
@ -2502,38 +2537,71 @@ namespace bgfx
}
}
void FrameBufferD3D9::destroy()
void FrameBufferD3D9::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat)
{
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
{
m_colorHandle[ii].idx = invalidHandle;
BX_UNUSED(_width, _height, _depthFormat);
IDirect3DSurface9* ptr = m_color[ii];
if (NULL != ptr)
{
ptr->Release();
m_color[ii] = NULL;
}
m_hwnd = (HWND)_nwh;
DX_CHECK(s_renderD3D9->m_device->CreateAdditionalSwapChain(&s_renderD3D9->m_params, &m_swapChain) );
DX_CHECK(m_swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &m_color[0]) );
m_colorHandle[0].idx = invalidHandle;
m_depthStencil = NULL;
m_denseIdx = _denseIdx;
m_num = 1;
m_needResolve = false;
}
uint16_t FrameBufferD3D9::destroy()
{
if (NULL != m_hwnd)
{
DX_RELEASE(m_color[0], 0);
DX_RELEASE(m_swapChain, 0);
}
if (NULL != m_depthStencil)
else
{
if (0 == m_num)
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
{
IDirect3DSurface9* ptr = m_color[0];
m_colorHandle[ii].idx = invalidHandle;
IDirect3DSurface9* ptr = m_color[ii];
if (NULL != ptr)
{
ptr->Release();
m_color[0] = NULL;
m_color[ii] = NULL;
}
}
m_depthStencil->Release();
m_depthStencil = NULL;
if (NULL != m_depthStencil)
{
if (0 == m_num)
{
IDirect3DSurface9* ptr = m_color[0];
if (NULL != ptr)
{
ptr->Release();
m_color[0] = NULL;
}
}
m_depthStencil->Release();
m_depthStencil = NULL;
}
}
m_hwnd = NULL;
m_num = 0;
m_depthHandle.idx = invalidHandle;
uint16_t denseIdx = m_denseIdx;
m_denseIdx = UINT16_MAX;
return denseIdx;
}
HRESULT FrameBufferD3D9::present()
{
return m_swapChain->Present(NULL, NULL, m_hwnd, NULL, 0);
}
void FrameBufferD3D9::resolve() const
@ -2556,57 +2624,78 @@ namespace bgfx
void FrameBufferD3D9::preReset()
{
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
if (NULL != m_hwnd)
{
m_color[ii]->Release();
m_color[ii] = NULL;
DX_RELEASE(m_color[0], 0);
DX_RELEASE(m_swapChain, 0);
}
if (isValid(m_depthHandle) )
else
{
if (0 == m_num)
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
{
m_color[0]->Release();
m_color[0] = NULL;
m_color[ii]->Release();
m_color[ii] = NULL;
}
m_depthStencil->Release();
m_depthStencil = NULL;
if (isValid(m_depthHandle) )
{
if (0 == m_num)
{
m_color[0]->Release();
m_color[0] = NULL;
}
m_depthStencil->Release();
m_depthStencil = NULL;
}
}
}
void FrameBufferD3D9::postReset()
{
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
if (NULL != m_hwnd)
{
TextureD3D9& texture = s_renderD3D9->m_textures[m_colorHandle[ii].idx];
if (NULL != texture.m_surface)
{
m_color[ii] = texture.m_surface;
m_color[ii]->AddRef();
}
else
{
DX_CHECK(texture.m_texture2d->GetSurfaceLevel(0, &m_color[ii]) );
}
DX_CHECK(s_renderD3D9->m_device->CreateAdditionalSwapChain(&s_renderD3D9->m_params, &m_swapChain) );
DX_CHECK(m_swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &m_color[0]) );
}
if (isValid(m_depthHandle) )
else
{
TextureD3D9& texture = s_renderD3D9->m_textures[m_depthHandle.idx];
if (NULL != texture.m_surface)
for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
{
m_depthStencil = texture.m_surface;
m_depthStencil->AddRef();
}
else
{
DX_CHECK(texture.m_texture2d->GetSurfaceLevel(0, &m_depthStencil) );
TextureHandle th = m_colorHandle[ii];
if (isValid(th) )
{
TextureD3D9& texture = s_renderD3D9->m_textures[th.idx];
if (NULL != texture.m_surface)
{
m_color[ii] = texture.m_surface;
m_color[ii]->AddRef();
}
else
{
DX_CHECK(texture.m_texture2d->GetSurfaceLevel(0, &m_color[ii]) );
}
}
}
if (0 == m_num)
if (isValid(m_depthHandle) )
{
createNullColorRT();
TextureD3D9& texture = s_renderD3D9->m_textures[m_depthHandle.idx];
if (NULL != texture.m_surface)
{
m_depthStencil = texture.m_surface;
m_depthStencil->AddRef();
}
else
{
DX_CHECK(texture.m_texture2d->GetSurfaceLevel(0, &m_depthStencil) );
}
if (0 == m_num)
{
createNullColorRT();
}
}
}
}

View file

@ -353,14 +353,18 @@ namespace bgfx
struct FrameBufferD3D9
{
FrameBufferD3D9()
: m_num(0)
: m_hwnd(NULL)
, m_denseIdx(UINT16_MAX)
, m_num(0)
, m_needResolve(0)
{
m_depthHandle.idx = invalidHandle;
}
void create(uint8_t _num, const TextureHandle* _handles);
void destroy();
void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
uint16_t destroy();
HRESULT present();
void resolve() const;
void preReset();
void postReset();
@ -368,8 +372,12 @@ namespace bgfx
IDirect3DSurface9* m_color[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
IDirect3DSurface9* m_depthStencil;
IDirect3DSwapChain9* m_swapChain;
HWND m_hwnd;
TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
TextureHandle m_depthHandle;
uint16_t m_denseIdx;
uint8_t m_num;
bool m_needResolve;
};

View file

@ -826,7 +826,8 @@ namespace bgfx
struct RendererContextGL : public RendererContextI
{
RendererContextGL()
: m_rtMsaa(false)
: m_numWindows(1)
, m_rtMsaa(false)
, m_capture(NULL)
, m_captureSize(0)
, m_maxAnisotropy(0.0f)
@ -1376,6 +1377,10 @@ namespace bgfx
{
if (m_flip)
{
for (uint32_t ii = 1, num = m_numWindows; ii < num; ++ii)
{
m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain);
}
m_glctx.swap();
}
}
@ -1491,9 +1496,26 @@ namespace bgfx
m_frameBuffers[_handle.idx].create(_num, _textureHandles);
}
void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat) BX_OVERRIDE
{
uint16_t denseIdx = m_numWindows++;
m_windows[denseIdx] = _handle;
m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _depthFormat);
}
void destroyFrameBuffer(FrameBufferHandle _handle) BX_OVERRIDE
{
m_frameBuffers[_handle.idx].destroy();
uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy();
if (UINT16_MAX != denseIdx)
{
--m_numWindows;
if (m_numWindows > 1)
{
FrameBufferHandle handle = m_windows[m_numWindows];
m_windows[denseIdx] = handle;
m_frameBuffers[handle.idx].m_denseIdx = denseIdx;
}
}
}
void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) BX_OVERRIDE
@ -1655,6 +1677,8 @@ namespace bgfx
frameBuffer.resolve();
}
m_glctx.makeCurrent(NULL);
if (!isValid(_fbh) )
{
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
@ -1662,8 +1686,17 @@ namespace bgfx
else
{
FrameBufferGL& frameBuffer = m_frameBuffers[_fbh.idx];
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) );
_height = frameBuffer.m_height;
if (UINT16_MAX != frameBuffer.m_denseIdx)
{
m_glctx.makeCurrent(frameBuffer.m_swapChain);
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
}
else
{
m_glctx.makeCurrent(NULL);
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) );
_height = frameBuffer.m_height;
}
}
m_fbh = _fbh;
@ -1764,8 +1797,7 @@ namespace bgfx
#if BX_PLATFORM_IOS
// iOS: need to figure out how to deal with FBO created by context.
m_backBufferFbo = m_glctx.m_fbo;
m_msaaBackBufferFbo = m_glctx.m_fbo;
m_backBufferFbo = m_msaaBackBufferFbo = m_glctx.getFbo()
#endif // BX_PLATFORM_IOS
}
else
@ -2203,6 +2235,9 @@ namespace bgfx
}
}
uint16_t m_numWindows;
FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
IndexBufferGL m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];
VertexBufferGL m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];
ShaderGL m_shaders[BGFX_CONFIG_MAX_SHADERS];
@ -3700,6 +3735,7 @@ namespace bgfx
GL_CHECK(glGenFramebuffers(1, &m_fbo[0]) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[0]) );
// m_denseIdx = UINT16_MAX;
bool needResolve = false;
GLenum buffers[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
@ -3807,11 +3843,31 @@ namespace bgfx
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, s_renderGL->m_msaaBackBufferFbo) );
}
void FrameBufferGL::destroy()
void FrameBufferGL::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat)
{
BX_UNUSED(_depthFormat);
m_swapChain = s_renderGL->m_glctx.createSwapChain(_nwh);
m_width = _width;
m_height = _height;
m_denseIdx = _denseIdx;
}
uint16_t FrameBufferGL::destroy()
{
GL_CHECK(glDeleteFramebuffers(0 == m_fbo[1] ? 1 : 2, m_fbo) );
memset(m_fbo, 0, sizeof(m_fbo) );
m_num = 0;
if (NULL != m_swapChain)
{
s_renderGL->m_glctx.destorySwapChain(m_swapChain);
m_swapChain = NULL;
}
uint16_t denseIdx = m_denseIdx;
m_denseIdx = UINT16_MAX;
return denseIdx;
}
void FrameBufferGL::resolve()
@ -3840,6 +3896,8 @@ namespace bgfx
void RendererContextGL::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
{
m_glctx.makeCurrent(NULL);
const GLuint defaultVao = s_renderGL->m_vao;
if (0 != defaultVao)
{
@ -4733,6 +4791,7 @@ namespace bgfx
}
}
m_glctx.makeCurrent(NULL);
int64_t now = bx::getHPCounter();
elapsed += now;

View file

@ -815,19 +815,24 @@ namespace bgfx
struct FrameBufferGL
{
FrameBufferGL()
: m_num(0)
: m_swapChain(NULL)
, m_denseIdx(UINT16_MAX)
, m_num(0)
{
memset(m_fbo, 0, sizeof(m_fbo) );
}
void create(uint8_t _num, const TextureHandle* _handles);
void destroy();
void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
uint16_t destroy();
void resolve();
uint8_t m_num;
SwapChainGL* m_swapChain;
GLuint m_fbo[2];
uint32_t m_width;
uint32_t m_height;
uint16_t m_denseIdx;
uint8_t m_num;
};
struct ProgramGL

View file

@ -121,6 +121,10 @@ namespace bgfx
{
}
void createFrameBuffer(FrameBufferHandle /*_handle*/, void* /*_nwh*/, uint32_t /*_width*/, uint32_t /*_height*/, TextureFormat::Enum /*_depthFormat*/) BX_OVERRIDE
{
}
void destroyFrameBuffer(FrameBufferHandle /*_handle*/) BX_OVERRIDE
{
}