Skip to content

Commit d4fdbdd

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 af2ba5a commit d4fdbdd

File tree

9 files changed

+275
-151
lines changed

9 files changed

+275
-151
lines changed

src/engine/renderer/Material.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,9 @@ void BindShaderHeatHaze( Material* material ) {
11711171
gl_heatHazeShaderMaterial->SetUniform_DeformEnable( true );
11721172

11731173
// draw to background image
1174+
if ( r_msaa.Get() ) {
1175+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
1176+
}
11741177
R_BindFBO( tr.mainFBO[1 - backEnd.currentMainFBO] );
11751178
}
11761179

@@ -2302,6 +2305,11 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID )
23022305
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
23032306

23042307
RenderIndirect( material, viewID );
2308+
2309+
if ( r_msaa.Get() ) {
2310+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
2311+
R_BindFBO( tr.msaaFBO );
2312+
}
23052313
}
23062314

23072315
if ( r_showTris->integer

src/engine/renderer/tr_backend.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,26 @@ GLuint64 GL_BindToTMU( int unit, image_t *image )
208208
return 0;
209209
}
210210

211+
void GL_BlitFBOToMSAA( FBO_t* fbo ) {
212+
R_BindFBO( GL_READ_FRAMEBUFFER, fbo );
213+
R_BindFBO( GL_DRAW_FRAMEBUFFER, tr.msaaFBO );
214+
glBlitFramebuffer( 0, 0, fbo->width, fbo->height, 0, 0, tr.msaaFBO->width, tr.msaaFBO->height,
215+
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST );
216+
217+
R_BindFBO( GL_DRAW_FRAMEBUFFER, fbo );
218+
glState.currentFBO = nullptr;
219+
}
220+
221+
void GL_BlitMSAAToFBO( FBO_t* fbo ) {
222+
R_BindFBO( GL_READ_FRAMEBUFFER, tr.msaaFBO );
223+
R_BindFBO( GL_DRAW_FRAMEBUFFER, fbo );
224+
glBlitFramebuffer( 0, 0, tr.msaaFBO->width, tr.msaaFBO->height, 0, 0, fbo->width, fbo->height,
225+
GL_COLOR_BUFFER_BIT /* | GL_DEPTH_BUFFER_BIT */, GL_NEAREST );
226+
227+
R_BindFBO( GL_READ_FRAMEBUFFER, fbo );
228+
glState.currentFBO = nullptr;
229+
}
230+
211231
void GL_BlendFunc( GLenum sfactor, GLenum dfactor )
212232
{
213233
if ( glState.blendSrc != ( signed ) sfactor || glState.blendDst != ( signed ) dfactor )
@@ -3082,6 +3102,9 @@ void RB_RenderBloom()
30823102

30833103
GL_PopMatrix(); // special 1/4th of the screen contrastRenderFBO ortho
30843104

3105+
if ( r_msaa.Get() ) {
3106+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
3107+
}
30853108
R_BindFBO( tr.contrastRenderFBO );
30863109
GL_ClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
30873110
glClear( GL_COLOR_BUFFER_BIT );
@@ -3148,6 +3171,11 @@ void RB_RenderBloom()
31483171
backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );
31493172
}
31503173

3174+
if ( r_msaa.Get() ) {
3175+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
3176+
R_BindFBO( tr.msaaFBO );
3177+
}
3178+
31513179
// go back to 3D
31523180
GL_PopMatrix();
31533181

@@ -3170,6 +3198,10 @@ void RB_RenderMotionBlur()
31703198

31713199
gl_motionblurShader->BindProgram( 0 );
31723200

3201+
if ( r_msaa.Get() ) {
3202+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
3203+
}
3204+
31733205
// Swap main FBOs
31743206
gl_motionblurShader->SetUniform_ColorMapBindless(
31753207
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
@@ -3196,6 +3228,11 @@ void RB_RenderMotionBlur()
31963228
backEnd.viewParms.viewportX, backEnd.viewParms.viewportY,
31973229
backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );
31983230

3231+
if ( r_msaa.Get() ) {
3232+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
3233+
R_BindFBO( tr.msaaFBO );
3234+
}
3235+
31993236
GL_PopMatrix();
32003237

32013238
GL_CheckErrors();
@@ -4628,7 +4665,11 @@ static void RB_RenderView( bool depthPass )
46284665
backEnd.pc.c_surfaces += backEnd.viewParms.numDrawSurfs;
46294666

46304667
// disable offscreen rendering
4631-
R_BindFBO( tr.mainFBO[ backEnd.currentMainFBO ] );
4668+
if ( r_msaa.Get() ) {
4669+
R_BindFBO( tr.msaaFBO );
4670+
} else {
4671+
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
4672+
}
46324673

46334674
// we will need to change the projection matrix before drawing
46344675
// 2D images again

src/engine/renderer/tr_fbo.cpp

Lines changed: 26 additions & 8 deletions
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)