Skip to content

Commit

Permalink
Enabled render passes without attachments (close #437)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Sep 15, 2023
1 parent 686b852 commit 5a4f646
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 38 deletions.
2 changes: 1 addition & 1 deletion Graphics/GraphicsEngine/include/DeviceContextBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,7 @@ inline bool DeviceContextBase<ImplementationTraits>::SetSubpassRenderTargets()
m_FramebufferWidth = FBDesc.Width;
m_FramebufferHeight = FBDesc.Height;
m_FramebufferSlices = FBDesc.NumArraySlices;
VERIFY_EXPR(m_FramebufferSamples > 0);
VERIFY_EXPR((m_FramebufferSamples > 0) || (Subpass.RenderTargetAttachmentCount == 0 && Subpass.pDepthStencilAttachment == nullptr));

return BindRenderTargets;
}
Expand Down
4 changes: 3 additions & 1 deletion Graphics/GraphicsEngineOpenGL/include/FBOCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ class FBOCache
static GLObjectWrappers::GLFrameBufferObj CreateFBO(GLContextState& ContextState,
Uint32 NumRenderTargets,
TextureViewGLImpl* ppRTVs[],
TextureViewGLImpl* pDSV);
TextureViewGLImpl* pDSV,
Uint32 DefaultWidth = 0,
Uint32 DefaultHeight = 0);

const GLObjectWrappers::GLFrameBufferObj& GetFBO(Uint32 NumRenderTargets,
TextureViewGLImpl* ppRTVs[],
Expand Down
81 changes: 52 additions & 29 deletions Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ void FBOCache::OnReleaseTexture(ITexture* pTexture)
GLObjectWrappers::GLFrameBufferObj FBOCache::CreateFBO(GLContextState& ContextState,
Uint32 NumRenderTargets,
TextureViewGLImpl* ppRTVs[],
TextureViewGLImpl* pDSV)
TextureViewGLImpl* pDSV,
Uint32 DefaultWidth,
Uint32 DefaultHeight)
{
GLObjectWrappers::GLFrameBufferObj FBO{true};

Expand Down Expand Up @@ -167,35 +169,56 @@ GLObjectWrappers::GLFrameBufferObj FBOCache::CreateFBO(GLContextState& Contex
pDepthTexGL->AttachToFramebuffer(DSVDesc, AttachmentPoint);
}

// We now need to set mapping between shader outputs and
// color attachments. This largely redundant step is performed
// by glDrawBuffers()
// clang-format off
static constexpr GLenum DrawBuffers[] =
if (NumRenderTargets > 0)
{
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3,
GL_COLOR_ATTACHMENT4,
GL_COLOR_ATTACHMENT5,
GL_COLOR_ATTACHMENT6,
GL_COLOR_ATTACHMENT7,
GL_COLOR_ATTACHMENT8,
GL_COLOR_ATTACHMENT9,
GL_COLOR_ATTACHMENT10,
GL_COLOR_ATTACHMENT11,
GL_COLOR_ATTACHMENT12,
GL_COLOR_ATTACHMENT13,
GL_COLOR_ATTACHMENT14,
GL_COLOR_ATTACHMENT15
};
// clang-format on

// The state set by glDrawBuffers() is part of the state of the framebuffer.
// So it can be set up once and left it set.
glDrawBuffers(NumRenderTargets, DrawBuffers);
CHECK_GL_ERROR("Failed to set draw buffers via glDrawBuffers()");
// We now need to set mapping between shader outputs and
// color attachments. This largely redundant step is performed
// by glDrawBuffers()
static constexpr GLenum DrawBuffers[] =
{
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3,
GL_COLOR_ATTACHMENT4,
GL_COLOR_ATTACHMENT5,
GL_COLOR_ATTACHMENT6,
GL_COLOR_ATTACHMENT7,
GL_COLOR_ATTACHMENT8,
GL_COLOR_ATTACHMENT9,
GL_COLOR_ATTACHMENT10,
GL_COLOR_ATTACHMENT11,
GL_COLOR_ATTACHMENT12,
GL_COLOR_ATTACHMENT13,
GL_COLOR_ATTACHMENT14,
GL_COLOR_ATTACHMENT15,
};

// The state set by glDrawBuffers() is part of the state of the framebuffer.
// So it can be set up once and left it set.
glDrawBuffers(NumRenderTargets, DrawBuffers);
CHECK_GL_ERROR("Failed to set draw buffers via glDrawBuffers()");
}
else if (pDSV == nullptr)
{
// Framebuffer without attachments
DEV_CHECK_ERR(DefaultWidth > 0 && DefaultHeight > 0, "Framebuffer without attachment requires non-zero default width and height");
#ifdef GL_ARB_framebuffer_no_attachments
glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, DefaultWidth);
CHECK_GL_ERROR("Failed to set framebuffer default width");

glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, DefaultHeight);
CHECK_GL_ERROR("Failed to set framebuffer default height");

glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_LAYERS, 1);
CHECK_GL_ERROR("Failed to set framebuffer default layer count");

glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, 1);
CHECK_GL_ERROR("Failed to set framebuffer default sample count");
#else
DEV_ERROR("Framebuffers without attachments are not supported on this platform");
#endif
}

GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (Status != GL_FRAMEBUFFER_COMPLETE)
Expand Down
4 changes: 2 additions & 2 deletions Graphics/GraphicsEngineOpenGL/src/FramebufferGLImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ FramebufferGLImpl::FramebufferGLImpl(IReferenceCounters* pRefCounters,
}
auto RenderTargetFBO = UseDefaultFBO(SubpassDesc.RenderTargetAttachmentCount, ppRTVs, pDSV) ?
GLObjectWrappers::GLFrameBufferObj{false} :
FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRTVs, pDSV);
FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRTVs, pDSV, Desc.Width, Desc.Height);

GLObjectWrappers::GLFrameBufferObj ResolveFBO{false};
if (SubpassDesc.pResolveAttachments != nullptr)
Expand All @@ -126,7 +126,7 @@ FramebufferGLImpl::FramebufferGLImpl(IReferenceCounters* pRefCounters,
}
ResolveFBO = UseDefaultFBO(SubpassDesc.RenderTargetAttachmentCount, ppRsvlViews, nullptr) ?
GLObjectWrappers::GLFrameBufferObj{false} :
FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRsvlViews, nullptr);
FBOCache::CreateFBO(CtxState, SubpassDesc.RenderTargetAttachmentCount, ppRsvlViews, nullptr, Desc.Width, Desc.Height);
}

RenderTargetFBO.SetName(m_Desc.Name);
Expand Down
62 changes: 57 additions & 5 deletions Tests/DiligentCoreAPITest/src/ComputeShaderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,7 @@ TEST(ComputeShaderTest, GenerateMips_CSInterference)
pSwapChain->Present();
}


TEST(ComputeShaderTest, FillTexturePS)
static void TestFillTexturePS(bool UseRenderPass)
{
auto* pEnv = GPUTestingEnvironment::GetInstance();
auto* pDevice = pEnv->GetDevice();
Expand All @@ -295,6 +294,8 @@ TEST(ComputeShaderTest, FillTexturePS)
auto* pSwapChain = pEnv->GetSwapChain();
auto* pContext = pEnv->GetDeviceContext();

const auto& SCDesc = pSwapChain->GetDesc();

GPUTestingEnvironment::ScopedReset EnvironmentAutoReset;

RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain{pSwapChain, IID_TestingSwapChain};
Expand Down Expand Up @@ -335,6 +336,30 @@ TEST(ComputeShaderTest, FillTexturePS)
PSOCreateInfo.pVS = pVS;
PSOCreateInfo.pPS = pPS;

RefCntAutoPtr<IRenderPass> pRenderPass;
RefCntAutoPtr<IFramebuffer> pFramebuffer;
if (UseRenderPass)
{
SubpassDesc Subpass;
RenderPassDesc RPDesc;
RPDesc.Name = "Compute shader test - render pass";
RPDesc.pSubpasses = &Subpass;
RPDesc.SubpassCount = 1;
pDevice->CreateRenderPass(RPDesc, &pRenderPass);
ASSERT_TRUE(pRenderPass != nullptr);

PSOCreateInfo.GraphicsPipeline.pRenderPass = pRenderPass;

FramebufferDesc FBDesc;
FBDesc.Name = "Compute shader test - framebuffer";
FBDesc.pRenderPass = pRenderPass;
FBDesc.Width = SCDesc.Width;
FBDesc.Height = SCDesc.Height;
FBDesc.NumArraySlices = 1;
pDevice->CreateFramebuffer(FBDesc, &pFramebuffer);
ASSERT_TRUE(pFramebuffer != nullptr);
}

RefCntAutoPtr<IPipelineState> pPSO;
pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &pPSO);
ASSERT_NE(pPSO, nullptr);
Expand All @@ -345,18 +370,45 @@ TEST(ComputeShaderTest, FillTexturePS)
pPSO->CreateShaderResourceBinding(&pSRB, true);
ASSERT_NE(pSRB, nullptr);

ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()};
pContext->SetRenderTargets(1, pRTVs, pSwapChain->GetDepthBufferDSV(), RESOURCE_STATE_TRANSITION_MODE_TRANSITION);

pContext->SetPipelineState(pPSO);
pContext->CommitShaderResources(pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);

pContext->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_NONE);
if (UseRenderPass)
{
BeginRenderPassAttribs BeginRPAttribs;
BeginRPAttribs.pRenderPass = pRenderPass;
BeginRPAttribs.pFramebuffer = pFramebuffer;
pContext->BeginRenderPass(BeginRPAttribs);
}
else
{
pContext->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_NONE);
}

const auto& SCDesc = pSwapChain->GetDesc();
Viewport VP{SCDesc};
Viewport VP{SCDesc};
pContext->SetViewports(1, &VP, SCDesc.Width, SCDesc.Height);

pContext->Draw(DrawAttribs{3, DRAW_FLAG_VERIFY_ALL});

if (UseRenderPass)
{
pContext->EndRenderPass();
}

pSwapChain->Present();
}

TEST(ComputeShaderTest, FillTexturePS)
{
TestFillTexturePS(false);
}

TEST(ComputeShaderTest, FillTexturePS_InRenderPass)
{
TestFillTexturePS(true);
}

} // namespace

0 comments on commit 5a4f646

Please sign in to comment.