@@ -90,6 +90,36 @@ float4 main(in PSInput PSIn) : SV_Target
9090)"
9191};
9292
93+ const std::string PS4{
94+ R"(
95+ struct PSInput
96+ {
97+ float4 Pos : SV_POSITION;
98+ float4 Color : COLOR;
99+ };
100+
101+ struct PSOutput
102+ {
103+ float4 Color0 : SV_Target0;
104+ float4 Color1 : SV_Target1;
105+ float4 Color2 : SV_Target2;
106+ float4 Color3 : SV_Target3;
107+ float4 Color4 : SV_Target4;
108+ };
109+
110+ PSOutput main(in PSInput PSIn)
111+ {
112+ PSOutput Out;
113+ Out.Color0 = PSIn.Color;
114+ Out.Color1 = PSIn.Color;
115+ Out.Color2 = PSIn.Color;
116+ Out.Color3 = PSIn.Color;
117+ Out.Color4 = PSIn.Color;
118+ return Out;
119+ }
120+ )"
121+ };
122+
93123// clang-format on
94124
95125} // namespace HLSL
@@ -278,4 +308,90 @@ TEST_F(RenderTargetTest, RenderTargetWriteMask)
278308 }
279309}
280310
311+ TEST_F (RenderTargetTest, MultipleRenderTargetWriteMasks)
312+ {
313+ GPUTestingEnvironment* pEnv = GPUTestingEnvironment::GetInstance ();
314+ IRenderDevice* pDevice = pEnv->GetDevice ();
315+ IDeviceContext* pContext = pEnv->GetDeviceContext ();
316+ ISwapChain* pSwapChain = pEnv->GetSwapChain ();
317+ const SwapChainDesc& SCDesc = pSwapChain->GetDesc ();
318+
319+ ShaderCreateInfo ShaderCI;
320+ ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
321+ ShaderCI.ShaderCompiler = pEnv->GetDefaultCompiler (ShaderCI.SourceLanguage );
322+
323+ RefCntAutoPtr<IShader> pPS;
324+ {
325+ ShaderCI.Desc = {" Render Target Test PS" , SHADER_TYPE_PIXEL, true };
326+ ShaderCI.EntryPoint = " main" ;
327+ ShaderCI.Source = HLSL::PS4.c_str ();
328+ pDevice->CreateShader (ShaderCI, &pPS);
329+ ASSERT_NE (pPS, nullptr );
330+ }
331+
332+ const std::array<COLOR_MASK, 5 > ColorMasks = {COLOR_MASK_RED, COLOR_MASK_GREEN, COLOR_MASK_BLUE, COLOR_MASK_ALPHA, COLOR_MASK_ALL};
333+
334+ RefCntAutoPtr<IPipelineState> pPSO;
335+ {
336+ GraphicsPipelineStateCreateInfoX PSOCreateInfo{" RenderTargetTest.RenderTargetWriteMask" };
337+
338+ InputLayoutDescX InputLayout{{0u , 0u , 4u , VT_FLOAT32}};
339+
340+ PSOCreateInfo
341+ .SetPrimitiveTopology (PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
342+ .SetInputLayout (InputLayout)
343+ .AddShader (sm_Resources.pVS )
344+ .AddShader (pPS);
345+ PSOCreateInfo.GraphicsPipeline .RasterizerDesc .CullMode = CULL_MODE_NONE;
346+ PSOCreateInfo.GraphicsPipeline .DepthStencilDesc .DepthEnable = False;
347+ for (size_t i = 0 ; i < ColorMasks.size (); ++i)
348+ {
349+ PSOCreateInfo.AddRenderTarget (SCDesc.ColorBufferFormat );
350+ PSOCreateInfo.GraphicsPipeline .BlendDesc .RenderTargets [i].RenderTargetWriteMask = ColorMasks[i];
351+ }
352+
353+ pDevice->CreateGraphicsPipelineState (PSOCreateInfo, &pPSO);
354+ ASSERT_NE (pPSO, nullptr );
355+ }
356+
357+ std::array<RefCntAutoPtr<ITexture>, ColorMasks.size ()> pRTs;
358+ for (RefCntAutoPtr<ITexture>& pRT : pRTs)
359+ {
360+ pRT = pEnv->CreateTexture (" Render Target Test - RTV" , SCDesc.ColorBufferFormat , BIND_RENDER_TARGET, SCDesc.Width , SCDesc.Height );
361+ ASSERT_NE (pRT, nullptr );
362+ }
363+
364+ for (Uint32 rt = 0 ; rt < ColorMasks.size (); ++rt)
365+ {
366+ std::array<ITextureView*, ColorMasks.size ()> ppRTVs;
367+ std::array<float4, ColorMasks.size ()> ClearColors;
368+ for (size_t i = 0 ; i < ColorMasks.size (); ++i)
369+ {
370+ ppRTVs[i] = (i == rt) ?
371+ pSwapChain->GetCurrentBackBufferRTV () :
372+ pRTs[i]->GetDefaultView (TEXTURE_VIEW_RENDER_TARGET);
373+ ASSERT_NE (ppRTVs[i], nullptr );
374+
375+ ClearColors[i] = float4{sm_Rnd (), sm_Rnd (), sm_Rnd (), sm_Rnd ()};
376+ }
377+
378+ RenderReference (ColorMasks[rt], ClearColors[rt]);
379+
380+ pContext->SetRenderTargets (static_cast <Uint32>(ppRTVs.size ()), ppRTVs.data (), nullptr , RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
381+ for (size_t i = 0 ; i < ColorMasks.size (); ++i)
382+ {
383+ pContext->ClearRenderTarget (ppRTVs[i], ClearColors[i].Data (), RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
384+ }
385+
386+ IBuffer* pVBs[] = {sm_Resources.pColorsVB };
387+ pContext->SetVertexBuffers (0 , _countof (pVBs), pVBs, nullptr , RESOURCE_STATE_TRANSITION_MODE_TRANSITION, SET_VERTEX_BUFFERS_FLAG_RESET);
388+
389+ pContext->SetPipelineState (pPSO);
390+ pContext->CommitShaderResources (sm_Resources.pSRB , RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
391+ pContext->Draw ({6 , DRAW_FLAG_VERIFY_ALL});
392+
393+ pSwapChain->Present ();
394+ }
395+ }
396+
281397} // namespace
0 commit comments