From b2b9eec46bd66412678db52dee699fc23e61011f Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 18 Apr 2024 15:19:48 -0700 Subject: [PATCH] Render State Cache: added test for native multi draw --- .../InlineShaders/DrawCommandTestGLSL.h | 50 +++++- .../src/DrawCommandTest.cpp | 49 +----- .../src/RenderStateCacheTest.cpp | 160 ++++++++++++++++-- 3 files changed, 193 insertions(+), 66 deletions(-) diff --git a/Tests/DiligentCoreAPITest/include/InlineShaders/DrawCommandTestGLSL.h b/Tests/DiligentCoreAPITest/include/InlineShaders/DrawCommandTestGLSL.h index ee7c02f237..5f569330c5 100644 --- a/Tests/DiligentCoreAPITest/include/InlineShaders/DrawCommandTestGLSL.h +++ b/Tests/DiligentCoreAPITest/include/InlineShaders/DrawCommandTestGLSL.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 Diligent Graphics LLC + * Copyright 2019-2024 Diligent Graphics LLC * Copyright 2015-2019 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -127,6 +127,54 @@ void main() )" }; +const std::string DrawTest_VS_DrawId{ +R"( +#ifndef GL_ES +out gl_PerVertex +{ + vec4 gl_Position; +}; +#endif + +#ifdef VULKAN +# define gl_VertexID gl_VertexIndex +# define gl_InstanceID gl_InstanceIndex +# define OUT_LOCATION(X) layout(location=X) // Requires separable programs +#else +# define OUT_LOCATION(X) +#endif + +#if __VERSION__ >= 460 +# define DRAW_ID gl_DrawID +#else +# define DRAW_ID gl_DrawIDARB +#endif + +OUT_LOCATION(0) out vec3 _PSIn_Color; + +void main() +{ + vec4 Verts[6]; + + Verts[0] = vec4(-1.0, -0.5, 0.0, 1.0); + Verts[1] = vec4(-0.5, +0.5, 0.0, 1.0); + Verts[2] = vec4( 0.0, -0.5, 0.0, 1.0); + + Verts[3] = vec4(+0.0, -0.5, 0.0, 1.0); + Verts[4] = vec4(+0.5, +0.5, 0.0, 1.0); + Verts[5] = vec4(+1.0, -0.5, 0.0, 1.0); + + vec3 Colors[3]; + Colors[0] = vec3(1.0, 0.0, 0.0); + Colors[1] = vec3(0.0, 1.0, 0.0); + Colors[2] = vec3(0.0, 0.0, 1.0); + + gl_Position = Verts[DRAW_ID * 3 + gl_VertexID]; + _PSIn_Color = Colors[gl_VertexID]; +} +)" +}; + // clang-format on } // namespace GLSL diff --git a/Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp b/Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp index b9679f7bcd..e75e462d05 100644 --- a/Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp +++ b/Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp @@ -127,6 +127,7 @@ using namespace Diligent; using namespace Diligent::Testing; #include "InlineShaders/DrawCommandTestHLSL.h" +#include "InlineShaders/DrawCommandTestGLSL.h" namespace { @@ -406,54 +407,6 @@ void main() )" }; -const std::string DrawTest_VS_DrawId{ -R"( -#ifndef GL_ES -out gl_PerVertex -{ - vec4 gl_Position; -}; -#endif - -#ifdef VULKAN -# define gl_VertexID gl_VertexIndex -# define gl_InstanceID gl_InstanceIndex -# define OUT_LOCATION(X) layout(location=X) // Requires separable programs -#else -# define OUT_LOCATION(X) -#endif - -#if __VERSION__ >= 460 -# define DRAW_ID gl_DrawID -#else -# define DRAW_ID gl_DrawIDARB -#endif - -OUT_LOCATION(0) out vec3 _PSIn_Color; - -void main() -{ - vec4 Verts[6]; - - Verts[0] = vec4(-1.0, -0.5, 0.0, 1.0); - Verts[1] = vec4(-0.5, +0.5, 0.0, 1.0); - Verts[2] = vec4( 0.0, -0.5, 0.0, 1.0); - - Verts[3] = vec4(+0.0, -0.5, 0.0, 1.0); - Verts[4] = vec4(+0.5, +0.5, 0.0, 1.0); - Verts[5] = vec4(+1.0, -0.5, 0.0, 1.0); - - vec3 Colors[3]; - Colors[0] = vec3(1.0, 0.0, 0.0); - Colors[1] = vec3(0.0, 1.0, 0.0); - Colors[2] = vec3(0.0, 0.0, 1.0); - - gl_Position = Verts[DRAW_ID * 3 + gl_VertexID]; - _PSIn_Color = Colors[gl_VertexID]; -} -)" -}; - // clang-format on } // namespace GLSL diff --git a/Tests/DiligentCoreAPITest/src/RenderStateCacheTest.cpp b/Tests/DiligentCoreAPITest/src/RenderStateCacheTest.cpp index 24072fc6fc..db63dc443a 100644 --- a/Tests/DiligentCoreAPITest/src/RenderStateCacheTest.cpp +++ b/Tests/DiligentCoreAPITest/src/RenderStateCacheTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 Diligent Graphics LLC + * Copyright 2019-2024 Diligent Graphics LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +36,8 @@ #include "ResourceLayoutTestCommon.hpp" #include "InlineShaders/RayTracingTestHLSL.h" +#include "InlineShaders/DrawCommandTestHLSL.h" +#include "InlineShaders/DrawCommandTestGLSL.h" #include "gtest/gtest.h" @@ -252,6 +254,26 @@ RefCntAutoPtr CreateCache(IRenderDevice* pD return pCache; } +void CreateShader(IRenderStateCache* pCache, + const ShaderCreateInfo& ShaderCI, + bool PresentInCache, + RefCntAutoPtr& pShader) +{ + auto* const pEnv = GPUTestingEnvironment::GetInstance(); + auto* const pDevice = pEnv->GetDevice(); + + if (pCache != nullptr) + { + EXPECT_EQ(pCache->CreateShader(ShaderCI, &pShader), PresentInCache); + } + else + { + pDevice->CreateShader(ShaderCI, &pShader); + EXPECT_EQ(PresentInCache, false); + } + ASSERT_TRUE(pShader); +} + void CreateShader(IRenderStateCache* pCache, IShaderSourceInputStreamFactory* pShaderSourceFactory, SHADER_TYPE Type, @@ -260,8 +282,7 @@ void CreateShader(IRenderStateCache* pCache, bool PresentInCache, RefCntAutoPtr& pShader) { - auto* const pEnv = GPUTestingEnvironment::GetInstance(); - auto* const pDevice = pEnv->GetDevice(); + auto* const pEnv = GPUTestingEnvironment::GetInstance(); ShaderCreateInfo ShaderCI; ShaderCI.pShaderSourceStreamFactory = pShaderSourceFactory; @@ -270,21 +291,10 @@ void CreateShader(IRenderStateCache* pCache, constexpr ShaderMacro Macros[] = {{"EXTERNAL_MACROS", "2"}}; ShaderCI.Macros = {Macros, _countof(Macros)}; + ShaderCI.Desc = {Name, Type, true}; + ShaderCI.FilePath = Path; - { - ShaderCI.Desc = {Name, Type, true}; - ShaderCI.FilePath = Path; - if (pCache != nullptr) - { - EXPECT_EQ(pCache->CreateShader(ShaderCI, &pShader), PresentInCache); - } - else - { - pDevice->CreateShader(ShaderCI, &pShader); - EXPECT_EQ(PresentInCache, false); - } - ASSERT_TRUE(pShader); - } + CreateShader(pCache, ShaderCI, PresentInCache, pShader); } void CreateGraphicsShaders(IRenderStateCache* pCache, @@ -1429,4 +1439,120 @@ TEST(RenderStateCacheTest, Reload_Signatures2) } } +TEST(RenderStateCacheTest, GLExtensions) +{ + auto* pEnv = GPUTestingEnvironment::GetInstance(); + auto* pDevice = pEnv->GetDevice(); + auto* pCtx = pEnv->GetDeviceContext(); + auto* pSwapChain = pEnv->GetSwapChain(); + + if (!pDevice->GetDeviceInfo().IsVulkanDevice()) + GTEST_SKIP() << "This test is only applicable to Vulkan backend"; + + if (!pDevice->GetDeviceInfo().Features.NativeMultiDraw) + GTEST_SKIP() << "Native multi-draw is not supported"; + + GPUTestingEnvironment::ScopedReset AutoReset; + + auto CreateShaders = [](IRenderStateCache* pCache, + RefCntAutoPtr& pVS, + RefCntAutoPtr& pPS, + bool PresentInCache) { + { + ShaderCreateInfo ShaderCI; + ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; + ShaderCI.Desc = {"Render State Cache - Multi Draw VS", SHADER_TYPE_VERTEX, true}; + ShaderCI.Source = GLSL::DrawTest_VS_DrawId.c_str(); + ShaderCI.SourceLength = GLSL::DrawTest_VS_DrawId.length(); + CreateShader(pCache, ShaderCI, PresentInCache, pVS); + ASSERT_TRUE(pVS); + } + + { + ShaderCreateInfo ShaderCI; + ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + ShaderCI.Desc = {"Render State Cache - Multi Draw PS", SHADER_TYPE_PIXEL, true}; + ShaderCI.Source = HLSL::DrawTest_PS.c_str(); + ShaderCI.SourceLength = HLSL::DrawTest_PS.length(); + CreateShader(pCache, ShaderCI, PresentInCache, pPS); + ASSERT_TRUE(pPS); + } + }; + + static FastRandFloat rnd{1, 0, 1}; + for (Uint32 HotReload = 0; HotReload < 2; ++HotReload) + { + RefCntAutoPtr pData; + for (Uint32 pass = 0; pass < 3; ++pass) + { + // 0: empty cache + // 1: loaded cache + // 2: reloaded cache (loaded -> stored -> loaded) + + auto pCache = CreateCache(pDevice, HotReload, pData); + ASSERT_TRUE(pCache); + + { + RefCntAutoPtr pVS, pPS; + CreateShaders(pCache, pVS, pPS, pData != nullptr); + + const float ClearColor[] = {rnd(), rnd(), rnd(), rnd()}; + RenderDrawCommandReference(pSwapChain, ClearColor); + + { + GraphicsPipelineStateCreateInfo PSOCreateInfo; + + auto& PSODesc = PSOCreateInfo.PSODesc; + auto& GraphicsPipeline = PSOCreateInfo.GraphicsPipeline; + + PSODesc.Name = "Render State Cache Test - GLExtensions"; + + GraphicsPipeline.NumRenderTargets = 1; + GraphicsPipeline.RTVFormats[0] = pSwapChain->GetDesc().ColorBufferFormat; + GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE; + GraphicsPipeline.DepthStencilDesc.DepthEnable = False; + + PSOCreateInfo.pVS = pVS; + PSOCreateInfo.pPS = pPS; + + RefCntAutoPtr pPSO; + pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &pPSO); + ASSERT_NE(pPSO, nullptr); + + ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()}; + pCtx->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + pCtx->ClearRenderTarget(pRTVs[0], ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + pCtx->SetPipelineState(pPSO); + MultiDrawItem DrawItems[] = + { + {3, 0}, + {3, 0}, + }; + MultiDrawAttribs drawAttrs{_countof(DrawItems), DrawItems, DRAW_FLAG_VERIFY_ALL}; + pCtx->MultiDraw(drawAttrs); + + pSwapChain->Present(); + } + + RefCntAutoPtr pVS2, pPS2; + CreateShaders(pCache, pVS2, pPS2, true); + EXPECT_EQ(pVS, pVS2); + EXPECT_EQ(pPS, pPS); + } + + { + RefCntAutoPtr pVS, pPS; + CreateShaders(pCache, pVS, pPS, true); + } + + pData.Release(); + pCache->WriteToBlob(ContentVersion, &pData); + + if (HotReload) + EXPECT_EQ(pCache->Reload(), 0u); + } + } +} + } // namespace