networking
This commit is contained in:
356
external/steamworks/glmgr/cglmfbo.cpp
vendored
Normal file
356
external/steamworks/glmgr/cglmfbo.cpp
vendored
Normal file
@@ -0,0 +1,356 @@
|
||||
//============ Copyright (c) Valve Corporation, All rights reserved. ============
|
||||
//
|
||||
// cglmfbo.cpp
|
||||
//
|
||||
//===============================================================================
|
||||
|
||||
#include "glmgr.h"
|
||||
#include "cglmfbo.h"
|
||||
// #include "../shaderapidx9/dxabstract.h"
|
||||
|
||||
#ifdef OSX
|
||||
// Debugger - 10.8
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
CGLMFBO::CGLMFBO( GLMContext *ctx )
|
||||
{
|
||||
m_ctx = ctx;
|
||||
m_ctx->CheckCurrent();
|
||||
|
||||
glGenFramebuffersEXT( 1, &m_name );
|
||||
GLMCheckError();
|
||||
|
||||
memset( m_attach, 0, sizeof( m_attach ) );
|
||||
|
||||
m_sizeX = m_sizeY = 0;
|
||||
}
|
||||
|
||||
|
||||
CGLMFBO::~CGLMFBO( )
|
||||
{
|
||||
m_ctx->CheckCurrent();
|
||||
|
||||
// detach all known attached textures first... necessary ?
|
||||
for( int index = 0; index < kAttCount; index++)
|
||||
{
|
||||
if (m_attach[ index ].m_tex)
|
||||
{
|
||||
TexDetach( (EGLMFBOAttachment)index );
|
||||
GLMCheckError();
|
||||
}
|
||||
}
|
||||
|
||||
glDeleteFramebuffersEXT( 1, &m_name );
|
||||
GLMCheckError();
|
||||
|
||||
m_name = 0;
|
||||
m_ctx = NULL;
|
||||
}
|
||||
|
||||
// the tex attach path should also select a specific slice of the texture...
|
||||
// and we need a way to make renderbuffers..
|
||||
|
||||
static GLenum EncodeAttachmentFBO( EGLMFBOAttachment index )
|
||||
{
|
||||
if (index < kAttDepth)
|
||||
{
|
||||
return GL_COLOR_ATTACHMENT0_EXT + (int) index;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( index )
|
||||
{
|
||||
case kAttDepth:
|
||||
return GL_DEPTH_ATTACHMENT_EXT;
|
||||
break;
|
||||
|
||||
case kAttStencil:
|
||||
return GL_STENCIL_ATTACHMENT_EXT;
|
||||
break;
|
||||
|
||||
case kAttDepthStencil:
|
||||
return GL_DEPTH_STENCIL_ATTACHMENT_EXT;
|
||||
break;
|
||||
|
||||
default:
|
||||
GLMStop(); // bad news
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGLMFBO::TexAttach( GLMFBOTexAttachParams *params, EGLMFBOAttachment attachIndex, GLenum fboBindPoint )
|
||||
{
|
||||
// force our parent context to be current
|
||||
m_ctx->MakeCurrent();
|
||||
|
||||
// bind to context (will cause FBO object creation on first use)
|
||||
m_ctx->BindFBOToCtx( this, fboBindPoint );
|
||||
|
||||
// it's either a plain 2D, a 2D face of a cube map, or a slice of a 3D.
|
||||
CGLMTex *tex = params->m_tex;
|
||||
|
||||
// always detach what is currently there, if anything
|
||||
this->TexDetach( attachIndex, fboBindPoint );
|
||||
|
||||
if (!tex)
|
||||
{
|
||||
// andif they pass NULL to us, then we are done.
|
||||
return;
|
||||
}
|
||||
|
||||
GLMTexLayout *layout = tex->m_layout;
|
||||
GLenum target = tex->m_layout->m_key.m_texGLTarget;
|
||||
|
||||
GLenum attachIndexGL = EncodeAttachmentFBO( attachIndex );
|
||||
|
||||
switch( target )
|
||||
{
|
||||
case GL_TEXTURE_2D:
|
||||
{
|
||||
// we will attach the underlying RBO on a multisampled tex, iff the tex hasone, **and** we're not being asked to attach it to the read buffer.
|
||||
// if we get a req to attach an MSAA tex to the read buffer, chances are it's BlitTex calling, andit has already resolved the tex, so in those
|
||||
// cases you really do want to attach the texture and not the RBO to the FBO in question.
|
||||
|
||||
bool useRBO = false; // initial state
|
||||
|
||||
if (layout->m_key.m_texFlags & kGLMTexMultisampled)
|
||||
{
|
||||
// it is an MSAA tex
|
||||
if (fboBindPoint == GL_READ_FRAMEBUFFER_EXT)
|
||||
{
|
||||
// I think you just want to read a resolved tex.
|
||||
// But I will check that it is resolved first..
|
||||
Assert( tex->m_rboDirty == false );
|
||||
}
|
||||
else
|
||||
{
|
||||
// you want to draw into it. You get the RBO bound instead of the tex.
|
||||
useRBO = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (useRBO)
|
||||
{
|
||||
// MSAA path - attach the RBO, not the texture, and mark the RBO dirty
|
||||
if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT_EXT)
|
||||
{
|
||||
// you have to attach it both places...
|
||||
// http://www.opengl.org/wiki/GL_EXT_framebuffer_object
|
||||
|
||||
// bind the RBO to the GL_RENDERBUFFER_EXT target
|
||||
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, tex->m_rboName );
|
||||
GLMCheckError();
|
||||
|
||||
// attach the GL_RENDERBUFFER_EXT target to the depth and stencil attach points
|
||||
glFramebufferRenderbufferEXT( fboBindPoint, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, tex->m_rboName);
|
||||
GLMCheckError();
|
||||
|
||||
glFramebufferRenderbufferEXT( fboBindPoint, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, tex->m_rboName);
|
||||
GLMCheckError();
|
||||
|
||||
// no need to leave the RBO hanging on
|
||||
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
|
||||
GLMCheckError();
|
||||
}
|
||||
else
|
||||
{
|
||||
// color attachment (likely 0)
|
||||
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, tex->m_rboName );
|
||||
GLMCheckError();
|
||||
|
||||
glFramebufferRenderbufferEXT( fboBindPoint, attachIndexGL, GL_RENDERBUFFER_EXT, tex->m_rboName);
|
||||
GLMCheckError();
|
||||
|
||||
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
|
||||
GLMCheckError();
|
||||
}
|
||||
tex->m_rboDirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// regular path - attaching a texture2d
|
||||
|
||||
if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT_EXT)
|
||||
{
|
||||
// you have to attach it both places...
|
||||
// http://www.opengl.org/wiki/GL_EXT_framebuffer_object
|
||||
|
||||
glFramebufferTexture2DEXT( fboBindPoint, GL_DEPTH_ATTACHMENT_EXT, target, tex->m_texName, params->m_mip );
|
||||
GLMCheckError();
|
||||
|
||||
glFramebufferTexture2DEXT( fboBindPoint, GL_STENCIL_ATTACHMENT_EXT, target, tex->m_texName, params->m_mip );
|
||||
GLMCheckError();
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2DEXT( fboBindPoint, attachIndexGL, target, tex->m_texName, params->m_mip );
|
||||
GLMCheckError();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_3D:
|
||||
{
|
||||
glFramebufferTexture3DEXT( fboBindPoint, attachIndexGL, target, tex->m_texName, params->m_mip, params->m_zslice );
|
||||
GLMCheckError();
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
{
|
||||
// adjust target to steer to the proper face of the cube map
|
||||
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params->m_face;
|
||||
|
||||
glFramebufferTexture2DEXT( fboBindPoint, attachIndexGL, target, tex->m_texName, params->m_mip );
|
||||
GLMCheckError();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// log the attached tex
|
||||
m_attach[ attachIndex ] = *params;
|
||||
|
||||
// indicate that the tex has been bound to an RT
|
||||
tex->m_rtAttachCount++;
|
||||
}
|
||||
|
||||
void CGLMFBO::TexDetach( EGLMFBOAttachment attachIndex, GLenum fboBindPoint )
|
||||
{
|
||||
// force our parent context to be current
|
||||
m_ctx->MakeCurrent();
|
||||
|
||||
// bind to context (will cause FBO object creation on first use)
|
||||
m_ctx->BindFBOToCtx( this, fboBindPoint );
|
||||
|
||||
if (m_attach[ attachIndex ].m_tex)
|
||||
{
|
||||
CGLMTex *tex = m_attach[ attachIndex ].m_tex;
|
||||
GLMTexLayout *layout = tex->m_layout;
|
||||
GLenum target = tex->m_layout->m_key.m_texGLTarget;
|
||||
|
||||
GLenum attachIndexGL = EncodeAttachmentFBO( attachIndex );
|
||||
|
||||
switch( target )
|
||||
{
|
||||
case GL_TEXTURE_2D:
|
||||
{
|
||||
if (layout->m_key.m_texFlags & kGLMTexMultisampled)
|
||||
{
|
||||
// MSAA path - detach the RBO, not the texture
|
||||
// (is this the right time to resolve? probably better to wait until someone tries to sample the texture)
|
||||
|
||||
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
|
||||
GLMCheckError();
|
||||
|
||||
if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT_EXT)
|
||||
{
|
||||
// detach the GL_RENDERBUFFER_EXT target at depth and stencil attach points
|
||||
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
|
||||
GLMCheckError();
|
||||
|
||||
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
|
||||
GLMCheckError();
|
||||
}
|
||||
else
|
||||
{
|
||||
// color attachment (likely 0)
|
||||
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachIndexGL, GL_RENDERBUFFER_EXT, 0);
|
||||
GLMCheckError();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// plain tex detach
|
||||
if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT_EXT)
|
||||
{
|
||||
// you have to detach it both places...
|
||||
// http://www.opengl.org/wiki/GL_EXT_framebuffer_object
|
||||
|
||||
glFramebufferTexture2DEXT( fboBindPoint, GL_DEPTH_ATTACHMENT_EXT, 0,0,0 );
|
||||
glFramebufferTexture2DEXT( fboBindPoint, GL_STENCIL_ATTACHMENT_EXT, 0,0,0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2DEXT( fboBindPoint, attachIndexGL, 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_3D:
|
||||
{
|
||||
glFramebufferTexture3DEXT( fboBindPoint, attachIndexGL, 0, 0, 0, 0 );
|
||||
GLMCheckError();
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
{
|
||||
glFramebufferTexture2DEXT( fboBindPoint, attachIndexGL, 0, 0, 0 );
|
||||
GLMCheckError();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// un-log the attached tex
|
||||
memset( &m_attach[ attachIndex ], 0, sizeof( m_attach[0] ) );
|
||||
|
||||
// drop the RT attach count
|
||||
tex->m_rtAttachCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debugger(); // odd, but not harmful - typ comes from D3D code passing NULL into SetRenderTarget
|
||||
}
|
||||
}
|
||||
|
||||
void CGLMFBO::TexScrub( CGLMTex *tex )
|
||||
{
|
||||
// see if it's attached anywhere
|
||||
for( int attachIndex = 0; attachIndex < kAttCount; attachIndex++ )
|
||||
{
|
||||
if (m_attach[ attachIndex ].m_tex == tex)
|
||||
{
|
||||
// blammo
|
||||
TexDetach( (EGLMFBOAttachment)attachIndex, GL_DRAW_FRAMEBUFFER_EXT );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CGLMFBO::IsReady( void )
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
// ensure our parent context is current
|
||||
m_ctx->CheckCurrent();
|
||||
|
||||
// bind to context (will cause FBO object creation on first use)
|
||||
m_ctx->BindFBOToCtx( this );
|
||||
|
||||
GLenum status;
|
||||
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
switch(status)
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
result = true;
|
||||
break;
|
||||
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
result = false;
|
||||
Debugger();
|
||||
/* choose different formats */
|
||||
break;
|
||||
|
||||
default:
|
||||
result = false;
|
||||
Debugger();
|
||||
/* programming error; will fail on all hardware */
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user