Skip to content

Commit d503d9d

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 17e9107 commit d503d9d

8 files changed

Lines changed: 287 additions & 141 deletions

File tree

src/engine/renderer/Material.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1062,6 +1062,8 @@ void BindShaderHeatHaze( Material* material ) {
10621062
gl_heatHazeShaderMaterial->SetUniform_DeformEnable( true );
10631063

10641064
// draw to background image
1065+
TransitionMSAAToMain();
1066+
10651067
R_BindFBO( tr.mainFBO[1 - backEnd.currentMainFBO] );
10661068
}
10671069

@@ -2237,6 +2239,8 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID )
22372239
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
22382240

22392241
RenderIndirect( material, viewID );
2242+
2243+
TransitionMainToMSAA();
22402244
}
22412245

22422246
if ( r_showTris->integer

src/engine/renderer/tr_backend.cpp

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,53 @@ GLuint64 GL_BindToTMU( int unit, image_t *image )
199199
return 0;
200200
}
201201

202+
static void BlitFBOToMSAA( FBO_t* fbo ) {
203+
glState.currentFBO = nullptr;
204+
205+
R_BindFBO( GL_READ_FRAMEBUFFER, fbo );
206+
R_BindFBO( GL_DRAW_FRAMEBUFFER, tr.msaaFBO );
207+
glBlitFramebuffer( 0, 0, fbo->width, fbo->height, 0, 0, tr.msaaFBO->width, tr.msaaFBO->height,
208+
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST );
209+
210+
glState.currentFBO = nullptr;
211+
R_BindFBO( GL_DRAW_FRAMEBUFFER, fbo );
212+
glState.currentFBO = fbo;
213+
}
214+
215+
static void BlitMSAAToFBO( FBO_t* fbo ) {
216+
glState.currentFBO = nullptr;
217+
218+
R_BindFBO( GL_READ_FRAMEBUFFER, tr.msaaFBO );
219+
R_BindFBO( GL_DRAW_FRAMEBUFFER, fbo );
220+
glBlitFramebuffer( 0, 0, tr.msaaFBO->width, tr.msaaFBO->height, 0, 0, fbo->width, fbo->height,
221+
GL_COLOR_BUFFER_BIT /* | GL_DEPTH_BUFFER_BIT */, GL_NEAREST );
222+
223+
glState.currentFBO = nullptr;
224+
R_BindFBO( GL_READ_FRAMEBUFFER, fbo );
225+
glState.currentFBO = fbo;
226+
}
227+
228+
void TransitionMainToMSAA() {
229+
if ( glConfig.MSAA ) {
230+
BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
231+
R_BindFBO( tr.msaaFBO );
232+
}
233+
}
234+
235+
void TransitionMSAAToMain() {
236+
if ( glConfig.MSAA ) {
237+
BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
238+
}
239+
}
240+
241+
void BindMSAAOrMainFBO() {
242+
if ( glConfig.MSAA ) {
243+
R_BindFBO( tr.msaaFBO );
244+
} else {
245+
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
246+
}
247+
}
248+
202249
void GL_BlendFunc( GLenum sfactor, GLenum dfactor )
203250
{
204251
if ( glState.blendSrc != ( signed ) sfactor || glState.blendDst != ( signed ) dfactor )
@@ -797,7 +844,13 @@ void GL_TexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei wi
797844
GLint finalFormat = GL_ToSRGB( internalFormat, isSRGB );
798845

799846
glTexImage2D( target, level, finalFormat, width, height, border, format, type, data );
847+
}
848+
849+
void GL_TexImage2DMultisample( GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, bool fixedSampleLocations, bool isSRGB )
850+
{
851+
GLint finalFormat = GL_ToSRGB( internalFormat, isSRGB );
800852

853+
glTexImage2DMultisample( target, samples, finalFormat, width, height, fixedSampleLocations );
801854
}
802855

803856
void GL_TexImage3D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *data, bool isSRGB )
@@ -1365,7 +1418,8 @@ void RB_RenderPostDepthLightTile()
13651418
Tess_Clear();
13661419

13671420
// back to main image
1368-
R_BindFBO( tr.mainFBO[ backEnd.currentMainFBO ] );
1421+
BindMSAAOrMainFBO();
1422+
13691423
GL_Viewport( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY,
13701424
backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );
13711425
GL_Scissor( backEnd.viewParms.scissorX, backEnd.viewParms.scissorY,
@@ -1446,6 +1500,8 @@ void RB_RenderBloom()
14461500
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
14471501
);
14481502

1503+
TransitionMSAAToMain();
1504+
14491505
R_BindFBO( tr.contrastRenderFBO );
14501506
GL_ClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
14511507
glClear( GL_COLOR_BUFFER_BIT );
@@ -1510,6 +1566,8 @@ void RB_RenderBloom()
15101566
GL_PopMatrix();
15111567
}
15121568

1569+
TransitionMainToMSAA();
1570+
15131571
GL_CheckErrors();
15141572
}
15151573

@@ -1530,6 +1588,8 @@ void RB_RenderMotionBlur()
15301588

15311589
gl_motionblurShader->BindProgram();
15321590

1591+
TransitionMSAAToMain();
1592+
15331593
// Swap main FBOs
15341594
gl_motionblurShader->SetUniform_ColorMapBindless(
15351595
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
@@ -1545,6 +1605,8 @@ void RB_RenderMotionBlur()
15451605

15461606
Tess_InstantScreenSpaceQuad();
15471607

1608+
TransitionMainToMSAA();
1609+
15481610
GL_CheckErrors();
15491611
}
15501612

@@ -2666,7 +2728,7 @@ static void RB_RenderView( bool depthPass )
26662728
backEnd.pc.c_surfaces += backEnd.viewParms.numDrawSurfs;
26672729

26682730
// disable offscreen rendering
2669-
R_BindFBO( tr.mainFBO[ backEnd.currentMainFBO ] );
2731+
BindMSAAOrMainFBO();
26702732

26712733
// we will need to change the projection matrix before drawing
26722734
// 2D images again
@@ -2794,6 +2856,8 @@ static void RB_RenderPostProcess()
27942856
materialSystem.EndFrame();
27952857
}
27962858

2859+
TransitionMSAAToMain();
2860+
27972861
RB_FXAA();
27982862

27992863
// render chromatic aberration
@@ -3463,7 +3527,7 @@ const RenderCommand *ClearBufferCommand::ExecuteSelf( ) const
34633527
}
34643528

34653529
// disable offscreen rendering
3466-
R_BindFBO( tr.mainFBO[ backEnd.currentMainFBO ] );
3530+
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
34673531

34683532
// we will need to change the projection matrix before drawing
34693533
// 2D images again
@@ -3484,6 +3548,11 @@ const RenderCommand *ClearBufferCommand::ExecuteSelf( ) const
34843548

34853549
glClear( clearBits );
34863550

3551+
if ( glConfig.MSAA ) {
3552+
R_BindFBO( tr.msaaFBO );
3553+
glClear( clearBits );
3554+
}
3555+
34873556
return this + 1;
34883557
}
34893558

src/engine/renderer/tr_fbo.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ R_AttachFBOTexture2D
152152
*/
153153
void R_AttachFBOTexture2D( int target, int texId, int index )
154154
{
155-
if ( target != GL_TEXTURE_2D && ( target < GL_TEXTURE_CUBE_MAP_POSITIVE_X || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) )
155+
if ( target != GL_TEXTURE_2D && target != GL_TEXTURE_2D_MULTISAMPLE
156+
&& ( target < GL_TEXTURE_CUBE_MAP_POSITIVE_X || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) )
156157
{
157158
Log::Warn("R_AttachFBOTexture2D: invalid target %i", target );
158159
return;
@@ -194,6 +195,11 @@ void R_AttachFBOTexturePackedDepthStencil( int texId )
194195
GL_fboShim.glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, 0 );
195196
}
196197

198+
void R_AttachFBOTexturePackedDepthStencilMSAA( int texId ) {
199+
GL_fboShim.glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, texId, 0 );
200+
GL_fboShim.glFramebufferTexture2D( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, texId, 0 );
201+
}
202+
197203
/*
198204
============
199205
R_BindFBO
@@ -271,6 +277,17 @@ void R_InitFBOs()
271277
glConfig.usingReadonlyDepth = R_CheckFBO( tr.readonlyDepthFBO );
272278
}
273279

280+
if ( glConfig.MSAA ) {
281+
tr.msaaFBO = R_CreateFBO( "msaa", width, height );
282+
R_BindFBO( tr.msaaFBO );
283+
GL_CheckErrors();
284+
R_AttachFBOTexture2D( GL_TEXTURE_2D_MULTISAMPLE, tr.currentRenderImageMSAA->texnum, 0 );
285+
GL_CheckErrors();
286+
R_AttachFBOTexturePackedDepthStencilMSAA( tr.currentDepthImageMSAA->texnum );
287+
GL_CheckErrors();
288+
R_CheckFBO( tr.msaaFBO );
289+
}
290+
274291
if ( glConfig.realtimeLighting )
275292
{
276293
/* It's only required to create frame buffers only used by the

0 commit comments

Comments
 (0)