Skip to content

Commit 27484ca

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 8dd80ed commit 27484ca

File tree

9 files changed

+278
-144
lines changed

9 files changed

+278
-144
lines changed

src/engine/renderer/Material.cpp

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

947947
// draw to background image
948+
if ( r_msaa.Get() ) {
949+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
950+
}
948951
R_BindFBO( tr.mainFBO[1 - backEnd.currentMainFBO] );
949952
}
950953

@@ -2100,6 +2103,11 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID )
21002103
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
21012104

21022105
RenderIndirect( material, viewID );
2106+
2107+
if ( r_msaa.Get() ) {
2108+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
2109+
R_BindFBO( tr.msaaFBO );
2110+
}
21032111
}
21042112

21052113
if ( r_showTris->integer

src/engine/renderer/tr_backend.cpp

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

202+
void GL_BlitFBOToMSAA( FBO_t* fbo ) {
203+
R_BindFBO( GL_READ_FRAMEBUFFER, fbo );
204+
R_BindFBO( GL_DRAW_FRAMEBUFFER, tr.msaaFBO );
205+
glBlitFramebuffer( 0, 0, fbo->width, fbo->height, 0, 0, tr.msaaFBO->width, tr.msaaFBO->height,
206+
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST );
207+
208+
R_BindFBO( GL_DRAW_FRAMEBUFFER, fbo );
209+
glState.currentFBO = nullptr;
210+
}
211+
212+
void GL_BlitMSAAToFBO( FBO_t* fbo ) {
213+
R_BindFBO( GL_READ_FRAMEBUFFER, tr.msaaFBO );
214+
R_BindFBO( GL_DRAW_FRAMEBUFFER, fbo );
215+
glBlitFramebuffer( 0, 0, tr.msaaFBO->width, tr.msaaFBO->height, 0, 0, fbo->width, fbo->height,
216+
GL_COLOR_BUFFER_BIT /* | GL_DEPTH_BUFFER_BIT */, GL_NEAREST );
217+
218+
R_BindFBO( GL_READ_FRAMEBUFFER, fbo );
219+
glState.currentFBO = nullptr;
220+
}
221+
202222
void GL_BlendFunc( GLenum sfactor, GLenum dfactor )
203223
{
204224
if ( glState.blendSrc != ( signed ) sfactor || glState.blendDst != ( signed ) dfactor )
@@ -797,7 +817,13 @@ void GL_TexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei wi
797817
GLint finalFormat = GL_ToSRGB( internalFormat, isSRGB );
798818

799819
glTexImage2D( target, level, finalFormat, width, height, border, format, type, data );
820+
}
800821

822+
void GL_TexImage2DMultisample( GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, bool fixedSampleLocations, bool isSRGB )
823+
{
824+
GLint finalFormat = GL_ToSRGB( internalFormat, isSRGB );
825+
826+
glTexImage2DMultisample( target, samples, finalFormat, width, height, fixedSampleLocations );
801827
}
802828

803829
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 )
@@ -1431,6 +1457,10 @@ void RB_RenderBloom()
14311457
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
14321458
);
14331459

1460+
if ( r_msaa.Get() ) {
1461+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
1462+
}
1463+
14341464
R_BindFBO( tr.contrastRenderFBO );
14351465
GL_ClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
14361466
glClear( GL_COLOR_BUFFER_BIT );
@@ -1495,6 +1525,11 @@ void RB_RenderBloom()
14951525
GL_PopMatrix();
14961526
}
14971527

1528+
if ( r_msaa.Get() ) {
1529+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
1530+
R_BindFBO( tr.msaaFBO );
1531+
}
1532+
14981533
GL_CheckErrors();
14991534
}
15001535

@@ -1513,6 +1548,10 @@ void RB_RenderMotionBlur()
15131548

15141549
gl_motionblurShader->BindProgram( 0 );
15151550

1551+
if ( r_msaa.Get() ) {
1552+
GL_BlitMSAAToFBO( tr.mainFBO[backEnd.currentMainFBO] );
1553+
}
1554+
15161555
// Swap main FBOs
15171556
gl_motionblurShader->SetUniform_ColorMapBindless(
15181557
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
@@ -1528,6 +1567,11 @@ void RB_RenderMotionBlur()
15281567

15291568
Tess_InstantScreenSpaceQuad();
15301569

1570+
if ( r_msaa.Get() ) {
1571+
GL_BlitFBOToMSAA( tr.mainFBO[backEnd.currentMainFBO] );
1572+
R_BindFBO( tr.msaaFBO );
1573+
}
1574+
15311575
GL_CheckErrors();
15321576
}
15331577

@@ -2648,7 +2692,11 @@ static void RB_RenderView( bool depthPass )
26482692
backEnd.pc.c_surfaces += backEnd.viewParms.numDrawSurfs;
26492693

26502694
// disable offscreen rendering
2651-
R_BindFBO( tr.mainFBO[ backEnd.currentMainFBO ] );
2695+
if ( r_msaa.Get() ) {
2696+
R_BindFBO( tr.msaaFBO );
2697+
} else {
2698+
R_BindFBO( tr.mainFBO[backEnd.currentMainFBO] );
2699+
}
26522700

26532701
// we will need to change the projection matrix before drawing
26542702
// 2D images again

src/engine/renderer/tr_fbo.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ R_AttachFBOTexture2D
304304
*/
305305
void R_AttachFBOTexture2D( int target, int texId, int index )
306306
{
307-
if ( target != GL_TEXTURE_2D && ( target < GL_TEXTURE_CUBE_MAP_POSITIVE_X || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) )
307+
if ( target != GL_TEXTURE_2D && target != GL_TEXTURE_2D_MULTISAMPLE
308+
&& ( target < GL_TEXTURE_CUBE_MAP_POSITIVE_X || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ) )
308309
{
309310
Log::Warn("R_AttachFBOTexture2D: invalid target %i", target );
310311
return;
@@ -356,24 +357,31 @@ void R_AttachFBOTexturePackedDepthStencil( int texId )
356357
GL_fboShim.glFramebufferTexture2D( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, 0 );
357358
}
358359

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

372381
GLIMP_LOGCOMMENT( "--- R_BindFBO( %s ) ---", fbo->name );
373382

374-
if ( glState.currentFBO != fbo )
375-
{
376-
GL_fboShim.glBindFramebuffer( GL_FRAMEBUFFER, fbo->frameBuffer );
383+
if ( glState.currentFBO != fbo ) {
384+
GL_fboShim.glBindFramebuffer( target, fbo->frameBuffer );
377385

378386
glState.currentFBO = fbo;
379387
}
@@ -430,6 +438,17 @@ void R_InitFBOs()
430438
R_AttachFBOTexturePackedDepthStencil( tr.currentDepthImage->texnum );
431439
R_CheckFBO( tr.mainFBO[1] );
432440

441+
if( r_msaa.Get() ) {
442+
tr.msaaFBO = R_CreateFBO( "msaa", width, height );
443+
R_BindFBO( tr.msaaFBO );
444+
GL_CheckErrors();
445+
R_AttachFBOTexture2D( GL_TEXTURE_2D_MULTISAMPLE, tr.currentRenderImageMSAA->texnum, 0 );
446+
GL_CheckErrors();
447+
R_AttachFBOTexturePackedDepthStencilMSAA( tr.currentDepthImageMSAA->texnum );
448+
GL_CheckErrors();
449+
R_CheckFBO( tr.msaaFBO );
450+
}
451+
433452
if ( glConfig.realtimeLighting )
434453
{
435454
/* It's only required to create frame buffers only used by the

0 commit comments

Comments
 (0)