Skip to content

Commit 8350e3e

Browse files
Vulkan: fixed an issue with missing dynamic clear when changing render targets
1 parent e874721 commit 8350e3e

File tree

2 files changed

+134
-60
lines changed

2 files changed

+134
-60
lines changed

Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,7 @@ void DeviceContextVkImpl::ChooseRenderPassAndFramebuffer()
19571957
CreateRIAttribs.ShadingRateTexelSize.height = AlignUpToPowerOfTwo(m_FramebufferHeight / ShadingRateDesc.Height);
19581958
}
19591959

1960+
VERIFY(!m_DynamicRenderingInfo || !m_DynamicRenderingInfo->HasClears(), "There are pending clears in the dynamic render pass");
19601961
m_DynamicRenderingInfo = FramebufferCache::CreateDyanmicRenderInfo(FBKey, CreateRIAttribs);
19611962
}
19621963
}
@@ -1971,7 +1972,10 @@ void DeviceContextVkImpl::EndRenderScope()
19711972
CommitRenderPassAndFramebuffer(/*VerifyStates = */ false);
19721973
}
19731974

1974-
m_CommandBuffer.EndRenderScope();
1975+
if (m_CommandBuffer.GetVkCmdBuffer() != VK_NULL_HANDLE)
1976+
{
1977+
m_CommandBuffer.EndRenderScope();
1978+
}
19751979
}
19761980

19771981
void DeviceContextVkImpl::SetRenderTargetsExt(const SetRenderTargetsAttribs& Attribs)
@@ -1980,6 +1984,12 @@ void DeviceContextVkImpl::SetRenderTargetsExt(const SetRenderTargetsAttribs& Att
19801984

19811985
if (TDeviceContextBase::SetRenderTargets(Attribs))
19821986
{
1987+
if (m_DynamicRenderingInfo && m_DynamicRenderingInfo->HasClears())
1988+
{
1989+
// If there are pending clears, we must begin and end the render pass to apply the clears
1990+
CommitRenderPassAndFramebuffer(/*VerifyStates = */ false);
1991+
}
1992+
19831993
ChooseRenderPassAndFramebuffer();
19841994

19851995
// Set the viewport to match the render target size
@@ -1996,8 +2006,7 @@ void DeviceContextVkImpl::SetRenderTargetsExt(const SetRenderTargetsAttribs& Att
19962006
void DeviceContextVkImpl::ResetRenderTargets()
19972007
{
19982008
TDeviceContextBase::ResetRenderTargets();
1999-
if (m_CommandBuffer.GetVkCmdBuffer() != VK_NULL_HANDLE)
2000-
EndRenderScope();
2009+
EndRenderScope();
20012010
m_vkRenderPass = VK_NULL_HANDLE;
20022011
m_vkFramebuffer = VK_NULL_HANDLE;
20032012
m_DynamicRenderingInfo.reset();

Tests/DiligentCoreAPITest/src/ClearRenderTargetTest.cpp

Lines changed: 122 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -79,7 +79,7 @@ void ClearRenderTargetReference(IRenderDevice* pDevice,
7979
ISwapChain* pSwapChain,
8080
const float ClearColor[])
8181
{
82-
auto deviceType = pDevice->GetDeviceInfo().Type;
82+
RENDER_DEVICE_TYPE deviceType = pDevice->GetDeviceInfo().Type;
8383
switch (deviceType)
8484
{
8585
#if D3D11_SUPPORTED
@@ -125,27 +125,32 @@ void ClearRenderTargetReference(IRenderDevice* pDevice,
125125
}
126126
}
127127

128-
129-
TEST(ClearRenderTargetTest, AsRenderTarget)
128+
static void ReferenceClear(const float ClearColor[])
130129
{
131-
auto* pEnv = GPUTestingEnvironment::GetInstance();
132-
auto* pDevice = pEnv->GetDevice();
133-
auto* pSwapChain = pEnv->GetSwapChain();
134-
auto* pContext = pEnv->GetDeviceContext();
135-
136-
GPUTestingEnvironment::ScopedReset EnvironmentAutoReset;
137-
138-
RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain(pSwapChain, IID_TestingSwapChain);
130+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
131+
IRenderDevice* pDevice = pEnv->GetDevice();
132+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
133+
IDeviceContext* pContext = pEnv->GetDeviceContext();
139134

140-
constexpr float ClearColor[] = {0.25f, 0.5f, 0.75f, 1.0f};
141-
142-
if (pTestingSwapChain)
135+
if (RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain{pSwapChain, IID_TestingSwapChain})
143136
{
144137
pContext->Flush();
145138
pContext->InvalidateState();
146139
ClearRenderTargetReference(pDevice, pSwapChain, ClearColor);
147140
pTestingSwapChain->TakeSnapshot();
148141
}
142+
}
143+
144+
TEST(ClearRenderTargetTest, AsRenderTarget)
145+
{
146+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
147+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
148+
IDeviceContext* pContext = pEnv->GetDeviceContext();
149+
150+
GPUTestingEnvironment::ScopedReset EnvironmentAutoReset;
151+
152+
constexpr float ClearColor[] = {0.25f, 0.5f, 0.75f, 1.0f};
153+
ReferenceClear(ClearColor);
149154

150155
ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()};
151156
pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
@@ -158,41 +163,109 @@ TEST(ClearRenderTargetTest, AsRenderTarget)
158163
}
159164

160165

166+
TEST(ClearRenderTargetTest, ClearAfterClear)
167+
{
168+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
169+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
170+
IDeviceContext* pContext = pEnv->GetDeviceContext();
171+
172+
GPUTestingEnvironment::ScopedReset EnvironmentAutoReset;
173+
174+
constexpr float ClearColor0[] = {0.5f, 0.75f, 0.125f, 1.0f};
175+
constexpr float ClearColor1[] = {0.75f, 0.875f, 0.25f, 1.0f};
176+
ReferenceClear(ClearColor1);
177+
178+
ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()};
179+
pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
180+
pContext->ClearRenderTarget(pRTVs[0], ClearColor0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
181+
pContext->ClearRenderTarget(pRTVs[0], ClearColor1, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
182+
183+
pSwapChain->Present();
184+
}
185+
186+
187+
TEST(ClearRenderTargetTest, ResetRTsAfterClear)
188+
{
189+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
190+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
191+
IDeviceContext* pContext = pEnv->GetDeviceContext();
192+
193+
GPUTestingEnvironment::ScopedReset EnvironmentAutoReset;
194+
195+
constexpr float ClearColor[] = {0.125f, 0.375f, 0.5f, 1.0f};
196+
ReferenceClear(ClearColor);
197+
198+
ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()};
199+
pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
200+
pContext->ClearRenderTarget(pRTVs[0], ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
201+
pContext->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
202+
203+
pSwapChain->Present();
204+
}
205+
206+
207+
TEST(ClearRenderTargetTest, SetRTsAfterClear)
208+
{
209+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
210+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
211+
IDeviceContext* pContext = pEnv->GetDeviceContext();
212+
213+
GPUTestingEnvironment::ScopedReset EnvironmentAutoReset;
214+
215+
constexpr float ClearColor1[] = {0.125f, 0.375f, 0.5f, 1.0f};
216+
ReferenceClear(ClearColor1);
217+
218+
ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()};
219+
pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
220+
pContext->ClearRenderTarget(pRTVs[0], ClearColor1, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
221+
222+
TextureDesc TexDesc;
223+
TexDesc.Name = "ClearRenderTargetTest.SetRTsAfterClear";
224+
TexDesc.Type = RESOURCE_DIM_TEX_2D;
225+
TexDesc.Width = 512;
226+
TexDesc.Height = 512;
227+
TexDesc.Format = TEX_FORMAT_RGBA8_UNORM;
228+
TexDesc.BindFlags = BIND_RENDER_TARGET;
229+
RefCntAutoPtr<ITexture> pTex;
230+
pEnv->GetDevice()->CreateTexture(TexDesc, nullptr, &pTex);
231+
ASSERT_NE(pTex, nullptr);
232+
233+
pRTVs[0] = pTex->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET);
234+
pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
235+
constexpr float ClearColor2[] = {0.75f, 0.125f, 0.25f, 0.0f};
236+
pContext->ClearRenderTarget(pRTVs[0], ClearColor2, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
237+
238+
pSwapChain->Present();
239+
}
240+
241+
161242
TEST(ClearRenderTargetTest, AsAttachment)
162243
{
163-
auto* pEnv = GPUTestingEnvironment::GetInstance();
164-
auto* pDevice = pEnv->GetDevice();
244+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
245+
IRenderDevice* pDevice = pEnv->GetDevice();
165246
if (pDevice->GetDeviceInfo().Type == RENDER_DEVICE_TYPE_D3D12)
166247
{
167248
GTEST_SKIP() << "D3D12 does not allow render target clears within render pass";
168249
}
169250

170251
GPUTestingEnvironment::ScopedReset EnvironmentAutoReset;
171252

172-
auto* pSwapChain = pEnv->GetSwapChain();
173-
auto* pContext = pEnv->GetDeviceContext();
253+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
254+
IDeviceContext* pContext = pEnv->GetDeviceContext();
174255

175256
constexpr float ClearColor[] = {0.75f, 0.1875f, 0.375f, 1.0f};
176-
177-
RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain(pSwapChain, IID_TestingSwapChain);
178-
if (pTestingSwapChain)
179-
{
180-
pContext->Flush();
181-
pContext->InvalidateState();
182-
ClearRenderTargetReference(pDevice, pSwapChain, ClearColor);
183-
pTestingSwapChain->TakeSnapshot();
184-
}
257+
ReferenceClear(ClearColor);
185258

186259
RenderPassAttachmentDesc Attachments[1];
187-
auto* pRTV = pSwapChain->GetCurrentBackBufferRTV();
260+
ITextureView* pRTV = pSwapChain->GetCurrentBackBufferRTV();
188261
ASSERT_NE(pRTV, nullptr);
189-
const auto& BackBufferDesc = pRTV->GetTexture()->GetDesc();
190-
Attachments[0].Format = BackBufferDesc.Format;
191-
Attachments[0].SampleCount = static_cast<Uint8>(BackBufferDesc.SampleCount);
192-
Attachments[0].InitialState = RESOURCE_STATE_RENDER_TARGET;
193-
Attachments[0].FinalState = RESOURCE_STATE_RENDER_TARGET;
194-
Attachments[0].LoadOp = ATTACHMENT_LOAD_OP_DISCARD;
195-
Attachments[0].StoreOp = ATTACHMENT_STORE_OP_STORE;
262+
const TextureDesc& BackBufferDesc = pRTV->GetTexture()->GetDesc();
263+
Attachments[0].Format = BackBufferDesc.Format;
264+
Attachments[0].SampleCount = static_cast<Uint8>(BackBufferDesc.SampleCount);
265+
Attachments[0].InitialState = RESOURCE_STATE_RENDER_TARGET;
266+
Attachments[0].FinalState = RESOURCE_STATE_RENDER_TARGET;
267+
Attachments[0].LoadOp = ATTACHMENT_LOAD_OP_DISCARD;
268+
Attachments[0].StoreOp = ATTACHMENT_STORE_OP_STORE;
196269

197270
SubpassDesc Subpasses[1] = {};
198271

@@ -239,34 +312,26 @@ TEST(ClearRenderTargetTest, AsAttachment)
239312

240313
TEST(ClearRenderTargetTest, LoadOpClear)
241314
{
242-
auto* pEnv = GPUTestingEnvironment::GetInstance();
243-
auto* pDevice = pEnv->GetDevice();
244-
auto* pSwapChain = pEnv->GetSwapChain();
245-
auto* pContext = pEnv->GetDeviceContext();
315+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
316+
IRenderDevice* pDevice = pEnv->GetDevice();
317+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
318+
IDeviceContext* pContext = pEnv->GetDeviceContext();
246319

247320
GPUTestingEnvironment::ScopedReset EnvironmentAutoReset;
248321

249322
constexpr float ClearColor[] = {0.875f, 0.3125, 0.4375, 1.0f};
250-
251-
RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain(pSwapChain, IID_TestingSwapChain);
252-
if (pTestingSwapChain)
253-
{
254-
pContext->Flush();
255-
pContext->InvalidateState();
256-
ClearRenderTargetReference(pDevice, pSwapChain, ClearColor);
257-
pTestingSwapChain->TakeSnapshot();
258-
}
323+
ReferenceClear(ClearColor);
259324

260325
RenderPassAttachmentDesc Attachments[1];
261-
auto* pRTV = pSwapChain->GetCurrentBackBufferRTV();
326+
ITextureView* pRTV = pSwapChain->GetCurrentBackBufferRTV();
262327
ASSERT_NE(pRTV, nullptr);
263-
const auto& BackBufferDesc = pRTV->GetTexture()->GetDesc();
264-
Attachments[0].Format = BackBufferDesc.Format;
265-
Attachments[0].SampleCount = static_cast<Uint8>(BackBufferDesc.SampleCount);
266-
Attachments[0].InitialState = RESOURCE_STATE_RENDER_TARGET;
267-
Attachments[0].FinalState = RESOURCE_STATE_RENDER_TARGET;
268-
Attachments[0].LoadOp = ATTACHMENT_LOAD_OP_CLEAR;
269-
Attachments[0].StoreOp = ATTACHMENT_STORE_OP_STORE;
328+
const TextureDesc& BackBufferDesc = pRTV->GetTexture()->GetDesc();
329+
Attachments[0].Format = BackBufferDesc.Format;
330+
Attachments[0].SampleCount = static_cast<Uint8>(BackBufferDesc.SampleCount);
331+
Attachments[0].InitialState = RESOURCE_STATE_RENDER_TARGET;
332+
Attachments[0].FinalState = RESOURCE_STATE_RENDER_TARGET;
333+
Attachments[0].LoadOp = ATTACHMENT_LOAD_OP_CLEAR;
334+
Attachments[0].StoreOp = ATTACHMENT_STORE_OP_STORE;
270335

271336
SubpassDesc Subpasses[1] = {};
272337

0 commit comments

Comments
 (0)