Skip to content

Commit 9e131a9

Browse files
committed
Implement MSAA
Add `r_msaa`. When set to > 0, an MSAA FBO will be created with that many samples. This FBO will be used for rendering, other than when it requires sampling from current render/depth image. When such rendering is required the MSAA FBO will be blit into the main FBO and vice versa, to resolve the MSAA texture.
1 parent d8b3fe8 commit 9e131a9

File tree

10 files changed

+278
-152
lines changed

10 files changed

+278
-152
lines changed

src/engine/renderer/Material.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,9 @@ void BindShaderHeatHaze( Material* material ) {
982982
gl_heatHazeShaderMaterial->SetUniform_DeformEnable( true );
983983

984984
// draw to background image
985+
if ( r_msaa.Get() ) {
986+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
987+
}
985988
R_BindFBO( tr.mainFBO[1 - backEnd.currentMainFBO] );
986989
}
987990

@@ -2286,6 +2289,11 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID )
22862289
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
22872290

22882291
RenderIndirect( material, viewID );
2292+
2293+
if ( r_msaa.Get() ) {
2294+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
2295+
R_BindFBO( tr.msaaFBO );
2296+
}
22892297
}
22902298

22912299
if ( r_showTris->integer

src/engine/renderer/tr_backend.cpp

+44-1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,26 @@ GLuint64 GL_BindToTMU( int unit, image_t *image )
207207
return 0;
208208
}
209209

210+
void GL_BlitFBOToMSAA( FBO_t* fbo ) {
211+
R_BindFBO( GL_READ_FRAMEBUFFER, fbo );
212+
R_BindFBO( GL_DRAW_FRAMEBUFFER, tr.msaaFBO );
213+
glBlitFramebuffer( 0, 0, fbo->width, fbo->height, 0, 0, tr.msaaFBO->width, tr.msaaFBO->height,
214+
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST );
215+
216+
R_BindFBO( GL_DRAW_FRAMEBUFFER, fbo );
217+
glState.currentFBO = nullptr;
218+
}
219+
220+
void GL_BlitMSAAToFBO( FBO_t* fbo ) {
221+
R_BindFBO( GL_READ_FRAMEBUFFER, tr.msaaFBO );
222+
R_BindFBO( GL_DRAW_FRAMEBUFFER, fbo );
223+
glBlitFramebuffer( 0, 0, tr.msaaFBO->width, tr.msaaFBO->height, 0, 0, fbo->width, fbo->height,
224+
GL_COLOR_BUFFER_BIT /* | GL_DEPTH_BUFFER_BIT */, GL_NEAREST );
225+
226+
R_BindFBO( GL_READ_FRAMEBUFFER, fbo );
227+
glState.currentFBO = nullptr;
228+
}
229+
210230
void GL_BlendFunc( GLenum sfactor, GLenum dfactor )
211231
{
212232
if ( glState.blendSrc != ( signed ) sfactor || glState.blendDst != ( signed ) dfactor )
@@ -3027,6 +3047,10 @@ void RB_RenderBloom()
30273047
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
30283048
);
30293049

3050+
if ( r_msaa.Get() ) {
3051+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
3052+
}
3053+
30303054
R_BindFBO( tr.contrastRenderFBO );
30313055
GL_ClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
30323056
glClear( GL_COLOR_BUFFER_BIT );
@@ -3078,6 +3102,7 @@ void RB_RenderBloom()
30783102

30793103
gl_screenShader->SetUniform_CurrentMapBindless( GL_BindToTMU( 0, tr.bloomRenderFBOImage[flip ^ 1] ) );
30803104

3105+
<<<<<<< HEAD
30813106
GL_PushMatrix();
30823107

30833108
matrix_t ortho;
@@ -3091,6 +3116,11 @@ void RB_RenderBloom()
30913116
GL_PopMatrix();
30923117
}
30933118

3119+
if ( r_msaa.Get() ) {
3120+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
3121+
R_BindFBO( tr.msaaFBO );
3122+
}
3123+
30943124
GL_CheckErrors();
30953125
}
30963126

@@ -3110,6 +3140,10 @@ void RB_RenderMotionBlur()
31103140

31113141
gl_motionblurShader->BindProgram( 0 );
31123142

3143+
if ( r_msaa.Get() ) {
3144+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
3145+
}
3146+
31133147
// Swap main FBOs
31143148
gl_motionblurShader->SetUniform_ColorMapBindless(
31153149
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
@@ -3125,6 +3159,11 @@ void RB_RenderMotionBlur()
31253159

31263160
Tess_InstantScreenSpaceQuad();
31273161

3162+
if ( r_msaa.Get() ) {
3163+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
3164+
R_BindFBO( tr.msaaFBO );
3165+
}
3166+
31283167
GL_CheckErrors();
31293168
}
31303169

@@ -4552,7 +4591,11 @@ static void RB_RenderView( bool depthPass )
45524591
backEnd.pc.c_surfaces += backEnd.viewParms.numDrawSurfs;
45534592

45544593
// disable offscreen rendering
4555-
R_BindFBO( tr.mainFBO[ backEnd.currentMainFBO ] );
4594+
if ( r_msaa.Get() ) {
4595+
R_BindFBO( tr.msaaFBO );
4596+
} else {
4597+
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
4598+
}
45564599

45574600
// we will need to change the projection matrix before drawing
45584601
// 2D images again

src/engine/renderer/tr_fbo.cpp

+26-8
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ R_AttachFBOTexture2D
303303
*/
304304
void R_AttachFBOTexture2D( int target, int texId, int index )
305305
{
306-
if ( target != GL_TEXTURE_2D && ( target < GL_TEXTURE_CUBE_MAP_POSITIVE_X || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) )
306+
if ( target != GL_TEXTURE_2D && target != GL_TEXTURE_2D_MULTISAMPLE
307+
&& ( target < GL_TEXTURE_CUBE_MAP_POSITIVE_X || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) )
307308
{
308309
Log::Warn("R_AttachFBOTexture2D: invalid target %i", target );
309310
return;
@@ -355,28 +356,34 @@ void R_AttachFBOTexturePackedDepthStencil( int texId )
355356
GL_fboShim.glFramebufferTexture2D( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, 0 );
356357
}
357358

359+
void R_AttachFBOTexturePackedDepthStencilMSAA( int texId ) {
360+
GL_fboShim.glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, texId, 0 );
361+
GL_fboShim.glFramebufferTexture2D( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, texId, 0 );
362+
}
363+
358364
/*
359365
============
360366
R_BindFBO
361367
============
362368
*/
363369
void R_BindFBO( FBO_t *fbo )
364370
{
365-
if ( !fbo )
366-
{
371+
R_BindFBO( GL_FRAMEBUFFER, fbo );
372+
}
373+
374+
void R_BindFBO( const GLenum target, FBO_t* fbo ) {
375+
if ( !fbo ) {
367376
R_BindNullFBO();
368377
return;
369378
}
370379

371-
if ( r_logFile->integer )
372-
{
380+
if ( r_logFile->integer ) {
373381
// don't just call LogComment, or we will get a call to va() every frame!
374382
GLimp_LogComment( va( "--- R_BindFBO( %s ) ---\n", fbo->name ) );
375383
}
376384

377-
if ( glState.currentFBO != fbo )
378-
{
379-
GL_fboShim.glBindFramebuffer( GL_FRAMEBUFFER, fbo->frameBuffer );
385+
if ( glState.currentFBO != fbo ) {
386+
GL_fboShim.glBindFramebuffer( target, fbo->frameBuffer );
380387

381388
glState.currentFBO = fbo;
382389
}
@@ -436,6 +443,17 @@ void R_InitFBOs()
436443
R_AttachFBOTexturePackedDepthStencil( tr.currentDepthImage->texnum );
437444
R_CheckFBO( tr.mainFBO[1] );
438445

446+
if( r_msaa.Get() ) {
447+
tr.msaaFBO = R_CreateFBO( "msaa", width, height );
448+
R_BindFBO( tr.msaaFBO );
449+
GL_CheckErrors();
450+
R_AttachFBOTexture2D( GL_TEXTURE_2D_MULTISAMPLE, tr.currentRenderImageMSAA->texnum, 0 );
451+
GL_CheckErrors();
452+
R_AttachFBOTexturePackedDepthStencilMSAA( tr.currentDepthImageMSAA->texnum );
453+
GL_CheckErrors();
454+
R_CheckFBO( tr.msaaFBO );
455+
}
456+
439457
if ( glConfig2.realtimeLighting
440458
&& r_realtimeLightingRenderer.Get() == Util::ordinal( realtimeLightingRenderer_t::TILED ) )
441459
{

0 commit comments

Comments
 (0)