Skip to content

Commit 9b64c77

Browse files
Render state cache: few minor updates
1 parent cf8eb68 commit 9b64c77

File tree

1 file changed

+41
-16
lines changed

1 file changed

+41
-16
lines changed

Graphics/GraphicsTools/src/RenderStateCache.cpp

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@
3434
#include <unordered_set>
3535
#include <string>
3636

37+
#include "Archiver.h"
38+
#include "Dearchiver.h"
39+
#include "ArchiverFactory.h"
40+
#include "ArchiverFactoryLoader.h"
41+
3742
#include "ObjectBase.hpp"
3843
#include "ShaderBase.hpp"
3944
#include "RefCntAutoPtr.hpp"
4045
#include "SerializationDevice.h"
4146
#include "SerializedShader.h"
42-
#include "Archiver.h"
43-
#include "Dearchiver.h"
44-
#include "ArchiverFactory.h"
45-
#include "ArchiverFactoryLoader.h"
4647
#include "XXH128Hasher.hpp"
4748
#include "CallbackWrapper.hpp"
4849
#include "GraphicsUtilities.h"
@@ -94,6 +95,9 @@ namespace Diligent
9495

9596
class RenderStateCacheImpl;
9697

98+
99+
/// Reloadable shader implements the IShader interface and delegates all
100+
/// calls to the internal shader object, which can be replaced at run-time.
97101
class ReloadableShader final : public ObjectBase<IShader>
98102
{
99103
public:
@@ -120,10 +124,14 @@ class ReloadableShader final : public ObjectBase<IShader>
120124
}
121125
else
122126
{
127+
// This will handle implementation-specific interfaces such as ShaderD3D11Impl::IID_InternalImpl,
128+
// ShaderD3D12Impl::IID_InternalImpl, etc. requested by e.g. pipeline state implementations
129+
// (PipelineStateD3D11Impl, PipelineStateD3D12Impl, etc.)
123130
m_pShader->QueryInterface(IID, ppInterface);
124131
}
125132
}
126133

134+
// Delegate all calls to the internal shader object
127135
PROXY_CONST_METHOD(m_pShader, const ShaderDesc&, GetDesc)
128136
PROXY_CONST_METHOD(m_pShader, Int32, GetUniqueID)
129137
PROXY_METHOD1(m_pShader, void, SetUserData, IObject*, pUserData)
@@ -144,7 +152,7 @@ class ReloadableShader final : public ObjectBase<IShader>
144152
}
145153
catch (...)
146154
{
147-
LOG_ERROR("Failed to create reloadable shader");
155+
LOG_ERROR("Failed to create reloadable shader '", (CreateInfo.Desc.Name ? CreateInfo.Desc.Name : "<unnamed>"), "'.");
148156
}
149157
}
150158

@@ -158,6 +166,9 @@ class ReloadableShader final : public ObjectBase<IShader>
158166

159167
constexpr INTERFACE_ID ReloadableShader::IID_InternalImpl;
160168

169+
170+
/// Reloadable pipeline state implements the IPipelineState interface and delegates all
171+
/// calls to the internal pipeline object, which can be replaced at run-time.
161172
class ReloadablePipelineState final : public ObjectBase<IPipelineState>
162173
{
163174
public:
@@ -184,10 +195,14 @@ class ReloadablePipelineState final : public ObjectBase<IPipelineState>
184195
}
185196
else
186197
{
198+
// This will handle implementation-specific interfaces such as PipelineStateD3D11Impl::IID_InternalImpl,
199+
// PipelineStateD3D12Impl::IID_InternalImpl, etc. requested by e.g. device context implementations
200+
// (DeviceContextD3D11Impl::SetPipelineState, DeviceContextD3D12Impl::SetPipelineState, etc.)
187201
m_pPipeline->QueryInterface(IID, ppInterface);
188202
}
189203
}
190204

205+
// Delegate all calls to the internal pipeline object
191206
PROXY_CONST_METHOD(m_pPipeline, const PipelineStateDesc&, GetDesc)
192207
PROXY_CONST_METHOD(m_pPipeline, Int32, GetUniqueID)
193208
PROXY_METHOD1(m_pPipeline, void, SetUserData, IObject*, pUserData)
@@ -218,7 +233,7 @@ class ReloadablePipelineState final : public ObjectBase<IPipelineState>
218233
}
219234
catch (...)
220235
{
221-
LOG_ERROR("Failed to create reloadable shader");
236+
LOG_ERROR("Failed to create reloadable pipeline state '", (CreateInfo.PSODesc.Name ? CreateInfo.PSODesc.Name : "<unnamed>"), "'.");
222237
}
223238
}
224239

@@ -311,7 +326,7 @@ class RenderStateCacheImpl final : public ObjectBase<IRenderStateCache>
311326

312327
if (!m_pDearchiver->LoadArchive(pNewData))
313328
{
314-
LOG_ERROR_MESSAGE("Failed to load new render state data");
329+
LOG_ERROR_MESSAGE("Failed to add new render state data to existing archive");
315330
return false;
316331
}
317332

@@ -338,7 +353,9 @@ class RenderStateCacheImpl final : public ObjectBase<IRenderStateCache>
338353
m_pDearchiver->Reset();
339354
m_pArchiver->Reset();
340355
m_Shaders.clear();
356+
m_ReloadableShaders.clear();
341357
m_Pipelines.clear();
358+
m_ReloadablePipelines.clear();
342359
}
343360

344361
virtual Uint32 DILIGENT_CALL_TYPE Reload(ReloadGraphicsPipelineCallbackType ReloadGraphicsPipeline, void* pUserData) override final;
@@ -520,6 +537,7 @@ bool RenderStateCacheImpl::CreateShader(const ShaderCreateInfo& ShaderCI,
520537

521538
if (m_CI.EnableHotReload)
522539
{
540+
// Wrap shader in a reloadable shader object
523541
{
524542
std::lock_guard<std::mutex> Guard{m_ReloadableShadersMtx};
525543

@@ -541,7 +559,7 @@ bool RenderStateCacheImpl::CreateShader(const ShaderCreateInfo& ShaderCI,
541559
ReloadableShader::Create(this, pShader, _ShaderCI, ppShader);
542560

543561
std::lock_guard<std::mutex> Guard{m_ReloadableShadersMtx};
544-
m_ReloadableShaders.emplace(pShader, RefCntWeakPtr<IShader>(*ppShader));
562+
m_ReloadableShaders.emplace(pShader, RefCntWeakPtr<IShader>{*ppShader});
545563
}
546564
}
547565
else
@@ -569,7 +587,8 @@ bool RenderStateCacheImpl::CreateShaderInternal(const ShaderCreateInfo& ShaderCI
569587
// First, try to check if the shader has already been requested
570588
{
571589
std::lock_guard<std::mutex> Guard{m_ShadersMtx};
572-
auto it = m_Shaders.find(Hash);
590+
591+
auto it = m_Shaders.find(Hash);
573592
if (it != m_Shaders.end())
574593
{
575594
if (auto pShader = it->second.Lock())
@@ -639,14 +658,14 @@ bool RenderStateCacheImpl::CreateShaderInternal(const ShaderCreateInfo& ShaderCI
639658
{
640659
LOG_ERROR_MESSAGE("Description of shader '", (ShaderCI.Desc.Name != nullptr ? ShaderCI.Desc.Name : "<unnamed>"),
641660
"' does not match the description of the shader unpacked from the cache. This may be the result of a "
642-
"hash conflict, but the probability of this should be virtually zero.");
661+
"hash conflict, though the probability of this should be virtually zero.");
643662
}
644663
}
645664
}
646665

647666
// Next, try to find the shader in the archiver
648667
RefCntAutoPtr<IShader> pArchivedShader{m_pArchiver->GetShader(HashStr.c_str())};
649-
const auto FoundInArchive = pArchivedShader != nullptr;
668+
const auto FoundInArchive = (pArchivedShader != nullptr);
650669
if (!pArchivedShader)
651670
{
652671
auto ArchiveShaderCI = ShaderCI;
@@ -680,7 +699,7 @@ bool RenderStateCacheImpl::CreateShaderInternal(const ShaderCreateInfo& ShaderCI
680699
{
681700
LOG_ERROR_MESSAGE("Description of shader '", (ShaderCI.Desc.Name != nullptr ? ShaderCI.Desc.Name : "<unnamed>"),
682701
"' does not match the description of the shader recently added to the cache. This may be the result of a "
683-
"hash conflict, but the probability of this should be virtually zero.");
702+
"hash conflict, though the probability of this should be virtually zero.");
684703
}
685704
}
686705
else
@@ -932,7 +951,7 @@ void CreateRenderStateCache(const RenderStateCacheCreateInfo& CreateInfo,
932951
}
933952
catch (...)
934953
{
935-
LOG_ERROR("Failed to create the bytecode cache");
954+
LOG_ERROR("Failed to create the render state cache");
936955
}
937956
}
938957

@@ -1045,7 +1064,7 @@ bool RenderStateCacheImpl::CreatePipelineStateInternal(const CreateInfoType& PSO
10451064
{
10461065
LOG_ERROR_MESSAGE("Description of pipeline state '", (PSOCreateInfo.PSODesc.Name != nullptr ? PSOCreateInfo.PSODesc.Name : "<unnamed>"),
10471066
"' does not match the description of the pipeline unpacked from the cache. This may be the result of a "
1048-
"hash conflict, but the probability of this should be virtually zero.");
1067+
"hash conflict, though the probability of this should be virtually zero.");
10491068
}
10501069
}
10511070
}
@@ -1107,6 +1126,7 @@ Uint32 RenderStateCacheImpl::Reload(ReloadGraphicsPipelineCallbackType ReloadGra
11071126

11081127
Uint32 NumStatesReloaded = 0;
11091128

1129+
// Reload all shaders first
11101130
{
11111131
std::lock_guard<std::mutex> Guard{m_ReloadableShadersMtx};
11121132
for (auto shader_it : m_ReloadableShaders)
@@ -1127,6 +1147,9 @@ Uint32 RenderStateCacheImpl::Reload(ReloadGraphicsPipelineCallbackType ReloadGra
11271147
}
11281148
}
11291149

1150+
// Reload pipelines.
1151+
// Note that create info structs reference reloadable shaders, so that when pipelines
1152+
// are re-created, they will automatically use reloaded shaders.
11301153
{
11311154
std::lock_guard<std::mutex> Guard{m_ReloadablePipelinesMtx};
11321155
for (auto pso_it : m_ReloadablePipelines)
@@ -1141,7 +1164,7 @@ Uint32 RenderStateCacheImpl::Reload(ReloadGraphicsPipelineCallbackType ReloadGra
11411164
}
11421165
else
11431166
{
1144-
UNEXPECTED("Shader object is not a ReloadableShader");
1167+
UNEXPECTED("Pipeline state object is not a ReloadablePipelineState");
11451168
}
11461169
}
11471170
}
@@ -1160,7 +1183,8 @@ struct ReloadablePipelineState::CreateInfoWrapperBase : DynamicHeapObjectBase
11601183
m_ImtblSamplers{CI.PSODesc.ResourceLayout.ImmutableSamplers, CI.PSODesc.ResourceLayout.ImmutableSamplers + CI.PSODesc.ResourceLayout.NumImmutableSamplers},
11611184
m_ppSignatures{CI.ppResourceSignatures, CI.ppResourceSignatures + CI.ResourceSignaturesCount}
11621185
{
1163-
m_CI.PSODesc.Name = m_Strings.emplace(CI.PSODesc.Name ? CI.PSODesc.Name : "<unnamed>").first->c_str();
1186+
if (CI.PSODesc.Name != nullptr)
1187+
m_CI.PSODesc.Name = m_Strings.emplace(CI.PSODesc.Name).first->c_str();
11641188

11651189
for (auto& Var : m_Variables)
11661190
Var.Name = m_Strings.emplace(Var.Name).first->c_str();
@@ -1380,6 +1404,7 @@ bool ReloadablePipelineState::Reload(ReloadGraphicsPipelineCallbackType ReloadGr
13801404

13811405
RefCntAutoPtr<IPipelineState> pNewPSO;
13821406

1407+
// Note that the create info struct references reloadable shaders, so that the pipeline will use the updated shaders
13831408
const auto FoundInCache = m_pStateCache->CreatePipelineStateInternal(static_cast<const CreateInfoType&>(CreateInfo), &pNewPSO);
13841409

13851410
if (pNewPSO)

0 commit comments

Comments
 (0)