Skip to content

Commit

Permalink
Render State Cache: added test for native multi draw
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Apr 18, 2024
1 parent a3b9e7f commit 08fca45
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 66 deletions.
Original file line number Diff line number Diff line change
@@ -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");
Expand Down Expand Up @@ -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
Expand Down
49 changes: 1 addition & 48 deletions Tests/DiligentCoreAPITest/src/DrawCommandTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ using namespace Diligent;
using namespace Diligent::Testing;

#include "InlineShaders/DrawCommandTestHLSL.h"
#include "InlineShaders/DrawCommandTestGLSL.h"

namespace
{
Expand Down Expand Up @@ -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
Expand Down
160 changes: 143 additions & 17 deletions Tests/DiligentCoreAPITest/src/RenderStateCacheTest.cpp
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -36,6 +36,8 @@
#include "ResourceLayoutTestCommon.hpp"

#include "InlineShaders/RayTracingTestHLSL.h"
#include "InlineShaders/DrawCommandTestHLSL.h"
#include "InlineShaders/DrawCommandTestGLSL.h"

#include "gtest/gtest.h"

Expand Down Expand Up @@ -252,6 +254,26 @@ RefCntAutoPtr<IRenderStateCache> CreateCache(IRenderDevice* pD
return pCache;
}

void CreateShader(IRenderStateCache* pCache,
const ShaderCreateInfo& ShaderCI,
bool PresentInCache,
RefCntAutoPtr<IShader>& 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,
Expand All @@ -260,8 +282,7 @@ void CreateShader(IRenderStateCache* pCache,
bool PresentInCache,
RefCntAutoPtr<IShader>& pShader)
{
auto* const pEnv = GPUTestingEnvironment::GetInstance();
auto* const pDevice = pEnv->GetDevice();
auto* const pEnv = GPUTestingEnvironment::GetInstance();

ShaderCreateInfo ShaderCI;
ShaderCI.pShaderSourceStreamFactory = pShaderSourceFactory;
Expand All @@ -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,
Expand Down Expand Up @@ -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<IShader>& pVS,
RefCntAutoPtr<IShader>& 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<IDataBlob> 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<IShader> 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<IPipelineState> 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<IShader> pVS2, pPS2;
CreateShaders(pCache, pVS2, pPS2, true);
EXPECT_EQ(pVS, pVS2);
EXPECT_EQ(pPS, pPS);
}

{
RefCntAutoPtr<IShader> pVS, pPS;
CreateShaders(pCache, pVS, pPS, true);
}

pData.Release();
pCache->WriteToBlob(ContentVersion, &pData);

if (HotReload)
EXPECT_EQ(pCache->Reload(), 0u);
}
}
}

} // namespace

0 comments on commit 08fca45

Please sign in to comment.