Skip to content

Commit 3c7ac6a

Browse files
Added render target tests
1 parent 87a00e6 commit 3c7ac6a

File tree

2 files changed

+285
-1
lines changed

2 files changed

+285
-1
lines changed
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
/*
2+
* Copyright 2025 Diligent Graphics LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* In no event and under no legal theory, whether in tort (including negligence),
17+
* contract, or otherwise, unless required by applicable law (such as deliberate
18+
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
19+
* liable for any damages, including any direct, indirect, special, incidental,
20+
* or consequential damages of any character arising as a result of this License or
21+
* out of the use or inability to use the software (including but not limited to damages
22+
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23+
* all other commercial damages or losses), even if such Contributor has been advised
24+
* of the possibility of such damages.
25+
*/
26+
27+
#include "GPUTestingEnvironment.hpp"
28+
#include "TestingSwapChainBase.hpp"
29+
#include "GraphicsTypesX.hpp"
30+
#include "FastRand.hpp"
31+
32+
#include "gtest/gtest.h"
33+
34+
#include <array>
35+
36+
using namespace Diligent;
37+
using namespace Diligent::Testing;
38+
39+
namespace
40+
{
41+
42+
namespace HLSL
43+
{
44+
45+
// clang-format off
46+
const std::string VS{
47+
R"(
48+
struct VSInput
49+
{
50+
float4 Color : ATTRIB0;
51+
uint VertId : SV_VertexID;
52+
};
53+
54+
struct PSInput
55+
{
56+
float4 Pos : SV_POSITION;
57+
float4 Color : COLOR;
58+
};
59+
60+
void main(in VSInput VSIn,
61+
out PSInput PSIn)
62+
{
63+
float4 Pos[6];
64+
Pos[0] = float4(-1.0, -0.5, 0.0, 1.0);
65+
Pos[1] = float4(-0.5, +0.5, 0.0, 1.0);
66+
Pos[2] = float4( 0.0, -0.5, 0.0, 1.0);
67+
68+
Pos[3] = float4(+0.0, -0.5, 0.0, 1.0);
69+
Pos[4] = float4(+0.5, +0.5, 0.0, 1.0);
70+
Pos[5] = float4(+1.0, -0.5, 0.0, 1.0);
71+
72+
PSIn.Pos = Pos[VSIn.VertId];
73+
PSIn.Color = VSIn.Color;
74+
}
75+
)"
76+
};
77+
78+
const std::string PS{
79+
R"(
80+
struct PSInput
81+
{
82+
float4 Pos : SV_POSITION;
83+
float4 Color : COLOR;
84+
};
85+
86+
float4 main(in PSInput PSIn) : SV_Target
87+
{
88+
return PSIn.Color;
89+
}
90+
)"
91+
};
92+
93+
// clang-format on
94+
95+
} // namespace HLSL
96+
97+
98+
constexpr std::array<float4, 6> RefColors = {
99+
float4{1, 0, 0, 0.0},
100+
float4{0, 1, 0, 0.5},
101+
float4{0, 0, 1, 1.0},
102+
103+
float4{0, 1, 1, 1.0},
104+
float4{1, 0, 1, 0.5},
105+
float4{1, 1, 0, 0.0},
106+
};
107+
108+
class RenderTargetTest : public ::testing::Test
109+
{
110+
protected:
111+
static void SetUpTestSuite()
112+
{
113+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
114+
IRenderDevice* pDevice = pEnv->GetDevice();
115+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
116+
const SwapChainDesc& SCDesc = pSwapChain->GetDesc();
117+
118+
ShaderCreateInfo ShaderCI;
119+
ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
120+
ShaderCI.ShaderCompiler = pEnv->GetDefaultCompiler(ShaderCI.SourceLanguage);
121+
122+
{
123+
ShaderCI.Desc = {"Render Target Test VS", SHADER_TYPE_VERTEX, true};
124+
ShaderCI.EntryPoint = "main";
125+
ShaderCI.Source = HLSL::VS.c_str();
126+
pDevice->CreateShader(ShaderCI, &sm_Resources.pVS);
127+
ASSERT_NE(sm_Resources.pVS, nullptr);
128+
}
129+
130+
{
131+
ShaderCI.Desc = {"Render Target Test PS", SHADER_TYPE_PIXEL, true};
132+
ShaderCI.EntryPoint = "main";
133+
ShaderCI.Source = HLSL::PS.c_str();
134+
pDevice->CreateShader(ShaderCI, &sm_Resources.pPS);
135+
ASSERT_NE(sm_Resources.pPS, nullptr);
136+
}
137+
138+
GraphicsPipelineStateCreateInfoX PSOCreateInfo{"Render Target Test Reference"};
139+
140+
InputLayoutDescX InputLayout{{0u, 0u, 4u, VT_FLOAT32}};
141+
142+
PSOCreateInfo
143+
.AddRenderTarget(SCDesc.ColorBufferFormat)
144+
.SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
145+
.SetInputLayout(InputLayout)
146+
.AddShader(sm_Resources.pVS)
147+
.AddShader(sm_Resources.pPS);
148+
PSOCreateInfo.GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE;
149+
PSOCreateInfo.GraphicsPipeline.DepthStencilDesc.DepthEnable = False;
150+
151+
pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &sm_Resources.pPSO);
152+
ASSERT_NE(sm_Resources.pPSO, nullptr);
153+
154+
sm_Resources.pPSO->CreateShaderResourceBinding(&sm_Resources.pSRB, true);
155+
ASSERT_NE(sm_Resources.pSRB, nullptr);
156+
157+
sm_Resources.pColorsVB = pEnv->CreateBuffer({"Render Target Test - Ref Colors", sizeof(RefColors), BIND_VERTEX_BUFFER}, RefColors.data());
158+
ASSERT_NE(sm_Resources.pColorsVB, nullptr);
159+
160+
sm_Resources.pRT = pEnv->CreateTexture("Render Target Test - RTV", SCDesc.ColorBufferFormat, BIND_RENDER_TARGET | BIND_SHADER_RESOURCE, SCDesc.Width, SCDesc.Height);
161+
}
162+
163+
static void TearDownTestSuite()
164+
{
165+
sm_Resources = {};
166+
167+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
168+
pEnv->Reset();
169+
}
170+
171+
void RenderReference(COLOR_MASK Mask, const float4& ClearColor)
172+
{
173+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
174+
IDeviceContext* pContext = pEnv->GetDeviceContext();
175+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
176+
177+
RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain{pSwapChain, IID_TestingSwapChain};
178+
ASSERT_NE(pTestingSwapChain, nullptr);
179+
180+
std::array<float4, 6> Colors = RefColors;
181+
for (float4& Color : Colors)
182+
{
183+
if ((Mask & COLOR_MASK_RED) == 0)
184+
Color.r = ClearColor.r;
185+
if ((Mask & COLOR_MASK_GREEN) == 0)
186+
Color.g = ClearColor.g;
187+
if ((Mask & COLOR_MASK_BLUE) == 0)
188+
Color.b = ClearColor.b;
189+
if ((Mask & COLOR_MASK_ALPHA) == 0)
190+
Color.a = ClearColor.a;
191+
}
192+
193+
RefCntAutoPtr<IBuffer> pColorsVB = pEnv->CreateBuffer({"Render Target Test - Ref Colors", sizeof(Colors), BIND_VERTEX_BUFFER}, Colors.data());
194+
195+
ITextureView* pRTVs[] = {sm_Resources.pRT->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET)};
196+
pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
197+
pContext->ClearRenderTarget(pRTVs[0], ClearColor.Data(), RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
198+
199+
IBuffer* pVBs[] = {pColorsVB};
200+
pContext->SetVertexBuffers(0, _countof(pVBs), pVBs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, SET_VERTEX_BUFFERS_FLAG_RESET);
201+
pContext->SetPipelineState(sm_Resources.pPSO);
202+
pContext->CommitShaderResources(sm_Resources.pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
203+
pContext->Draw({6, DRAW_FLAG_VERIFY_ALL});
204+
205+
StateTransitionDesc Barrier{sm_Resources.pRT, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_COPY_SOURCE, STATE_TRANSITION_FLAG_UPDATE_STATE};
206+
pContext->TransitionResourceStates(1, &Barrier);
207+
208+
pContext->Flush();
209+
pContext->WaitForIdle();
210+
211+
pTestingSwapChain->TakeSnapshot(sm_Resources.pRT);
212+
213+
pContext->InvalidateState();
214+
}
215+
216+
struct Resources
217+
{
218+
RefCntAutoPtr<IPipelineState> pPSO;
219+
RefCntAutoPtr<IShader> pVS;
220+
RefCntAutoPtr<IShader> pPS;
221+
RefCntAutoPtr<IShaderResourceBinding> pSRB;
222+
RefCntAutoPtr<IBuffer> pColorsVB;
223+
RefCntAutoPtr<ITexture> pRT;
224+
};
225+
static Resources sm_Resources;
226+
static FastRandFloat sm_Rnd;
227+
};
228+
229+
RenderTargetTest::Resources RenderTargetTest::sm_Resources;
230+
FastRandFloat RenderTargetTest::sm_Rnd{31, 0.f, 1.f};
231+
232+
TEST_F(RenderTargetTest, RenderTargetWriteMask)
233+
{
234+
GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance();
235+
IRenderDevice* pDevice = pEnv->GetDevice();
236+
IDeviceContext* pContext = pEnv->GetDeviceContext();
237+
ISwapChain* pSwapChain = pEnv->GetSwapChain();
238+
const SwapChainDesc& SCDesc = pSwapChain->GetDesc();
239+
240+
for (COLOR_MASK Mask : {COLOR_MASK_RED, COLOR_MASK_GREEN, COLOR_MASK_BLUE, COLOR_MASK_ALPHA, COLOR_MASK_ALL})
241+
{
242+
float4 ClearColor{sm_Rnd(), sm_Rnd(), sm_Rnd(), sm_Rnd()};
243+
244+
RenderReference(Mask, ClearColor);
245+
246+
ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()};
247+
pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
248+
pContext->ClearRenderTarget(pRTVs[0], ClearColor.Data(), RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
249+
250+
RefCntAutoPtr<IPipelineState> pPSO;
251+
{
252+
GraphicsPipelineStateCreateInfoX PSOCreateInfo{"RenderTargetTest.RenderTargetWriteMask"};
253+
254+
InputLayoutDescX InputLayout{{0u, 0u, 4u, VT_FLOAT32}};
255+
256+
PSOCreateInfo
257+
.AddRenderTarget(SCDesc.ColorBufferFormat)
258+
.SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
259+
.SetInputLayout(InputLayout)
260+
.AddShader(sm_Resources.pVS)
261+
.AddShader(sm_Resources.pPS);
262+
PSOCreateInfo.GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE;
263+
PSOCreateInfo.GraphicsPipeline.DepthStencilDesc.DepthEnable = False;
264+
PSOCreateInfo.GraphicsPipeline.BlendDesc.RenderTargets[0].RenderTargetWriteMask = Mask;
265+
266+
pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &pPSO);
267+
ASSERT_NE(pPSO, nullptr);
268+
}
269+
270+
IBuffer* pVBs[] = {sm_Resources.pColorsVB};
271+
pContext->SetVertexBuffers(0, _countof(pVBs), pVBs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, SET_VERTEX_BUFFERS_FLAG_RESET);
272+
273+
pContext->SetPipelineState(pPSO);
274+
pContext->CommitShaderResources(sm_Resources.pSRB, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
275+
pContext->Draw({6, DRAW_FLAG_VERIFY_ALL});
276+
277+
pSwapChain->Present();
278+
}
279+
}
280+
281+
} // namespace

Tests/GPUTestFramework/include/TestingSwapChainBase.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2022 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");
@@ -149,6 +149,9 @@ class TestingSwapChainBase : public RefCountedObject<SwapChainCombinedBaseInterf
149149
m_pDSV = m_pDepthBuffer->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL);
150150
VERIFY_EXPR(m_pDSV != nullptr);
151151
}
152+
153+
m_ReferenceDataPitch = m_SwapChainDesc.Width * 4;
154+
m_ReferenceData.resize(m_ReferenceDataPitch * m_SwapChainDesc.Height);
152155
}
153156

154157
virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override

0 commit comments

Comments
 (0)