Skip to content

Commit

Permalink
Vulkan: Related fixes for buffer descriptor set cache.
Browse files Browse the repository at this point in the history
Includes some stats counter gathering and a few related refactors and
cleanups. Also includes a new overlay widget.

Bug: angleproject:5736
Change-Id: Ida8d2cd815c5b598c6a442dd9bbfdf51e9c05180
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2785431
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Charlie Lao <cclao@google.com>
Reviewed-by: Tim Van Patten <timvp@google.com>
  • Loading branch information
null77 authored and Commit Bot committed Apr 28, 2021
1 parent d7859d9 commit ccc0fba
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 49 deletions.
6 changes: 3 additions & 3 deletions scripts/code_generation_hashes/overlay_widgets.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"src/libANGLE/Overlay_autogen.cpp":
"77cb799b7e7cd9cea1a04e143ce55162",
"687de489c4864b1204b2ea7f6477a4dd",
"src/libANGLE/Overlay_autogen.h":
"4e4b35f85231fdf717540eff5da6e388",
"b62df749c99e35421e40ee6e620c5c74",
"src/libANGLE/gen_overlay_widgets.py":
"d14bb9becb623817675e4ff758b6d4f4",
"src/libANGLE/overlay_widgets.json":
"3ee58a46e52247a5a366b47c1094e38d"
"0114af385f690a27937bae02341d9bdf"
}
15 changes: 15 additions & 0 deletions src/libANGLE/OverlayWidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,21 @@ void AppendWidgetDataHelper::AppendVulkanDescriptorSetAllocations(const overlay:
AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
}

void AppendWidgetDataHelper::AppendVulkanShaderBufferDSHitRate(const overlay::Widget *widget,
const gl::Extents &imageExtent,
TextWidgetData *textWidget,
GraphWidgetData *graphWidget,
OverlayWidgetCounts *widgetCounts)
{
auto format = [](size_t maxValue) {
std::ostringstream text;
text << "Shader Buffer DS Hit Rate (Max: " << maxValue << "%)";
return text.str();
};

AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
}

void AppendWidgetDataHelper::AppendVulkanDynamicBufferAllocations(const overlay::Widget *widget,
const gl::Extents &imageExtent,
TextWidgetData *textWidget,
Expand Down
43 changes: 43 additions & 0 deletions src/libANGLE/Overlay_autogen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,49 @@ void Overlay::initOverlayWidgets()
}
}

{
RunningGraph *widget = new RunningGraph(60);
{
const int32_t fontSize = GetFontSize(0, kLargeFont);
const int32_t offsetX = -50;
const int32_t offsetY = 360;
const int32_t width = 6 * static_cast<uint32_t>(widget->runningValues.size());
const int32_t height = 100;

widget->type = WidgetType::RunningGraph;
widget->fontSize = fontSize;
widget->coords[0] = offsetX - width;
widget->coords[1] = offsetY;
widget->coords[2] = offsetX;
widget->coords[3] = offsetY + height;
widget->color[0] = 1.0f;
widget->color[1] = 0.0f;
widget->color[2] = 0.294117647059f;
widget->color[3] = 0.78431372549f;
}
mState.mOverlayWidgets[WidgetId::VulkanShaderBufferDSHitRate].reset(widget);
{
const int32_t fontSize = GetFontSize(kFontLayerSmall, kLargeFont);
const int32_t offsetX =
mState.mOverlayWidgets[WidgetId::VulkanShaderBufferDSHitRate]->coords[0];
const int32_t offsetY =
mState.mOverlayWidgets[WidgetId::VulkanShaderBufferDSHitRate]->coords[1];
const int32_t width = 40 * kFontGlyphWidths[fontSize];
const int32_t height = kFontGlyphHeights[fontSize];

widget->description.type = WidgetType::Text;
widget->description.fontSize = fontSize;
widget->description.coords[0] = offsetX;
widget->description.coords[1] = std::max(offsetY - height, 1);
widget->description.coords[2] = std::min(offsetX + width, -1);
widget->description.coords[3] = offsetY;
widget->description.color[0] = 1.0f;
widget->description.color[1] = 0.0f;
widget->description.color[2] = 0.294117647059f;
widget->description.color[3] = 1.0f;
}
}

{
RunningGraph *widget = new RunningGraph(120);
{
Expand Down
3 changes: 3 additions & 0 deletions src/libANGLE/Overlay_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ enum class WidgetId
VulkanWriteDescriptorSetCount,
// Descriptor Set Allocations.
VulkanDescriptorSetAllocations,
// Shader Buffer Descriptor Set Cache Hit Rate.
VulkanShaderBufferDSHitRate,
// Buffer Allocations Made By vk::DynamicBuffer.
VulkanDynamicBufferAllocations,

Expand All @@ -45,6 +47,7 @@ enum class WidgetId
PROC(VulkanSecondaryCommandBufferPoolWaste) \
PROC(VulkanWriteDescriptorSetCount) \
PROC(VulkanDescriptorSetAllocations) \
PROC(VulkanShaderBufferDSHitRate) \
PROC(VulkanDynamicBufferAllocations)

} // namespace gl
1 change: 1 addition & 0 deletions src/libANGLE/Program.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ class Program final : public LabeledObject, public angle::Subject, public HasAtt

// Peek whether there is any running linking tasks.
bool isLinking() const;
bool hasLinkingState() const { return mLinkingState != nullptr; }

bool isLinked() const
{
Expand Down
16 changes: 16 additions & 0 deletions src/libANGLE/overlay_widgets.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@
"length": 40
}
},
{
"name": "VulkanShaderBufferDSHitRate",
"comment": "Shader Buffer Descriptor Set Cache Hit Rate.",
"type": "RunningGraph(60)",
"color": [255, 0, 75, 200],
"coords": [-50, 360],
"bar_width": 6,
"height": 100,
"description": {
"color": [255, 0, 75, 255],
"coords": ["VulkanShaderBufferDSHitRate.left.align",
"VulkanShaderBufferDSHitRate.top.adjacent"],
"font": "small",
"length": 40
}
},
{
"name": "VulkanDynamicBufferAllocations",
"comment": "Buffer Allocations Made By vk::DynamicBuffer.",
Expand Down
40 changes: 34 additions & 6 deletions src/libANGLE/renderer/vulkan/ContextVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1956,33 +1956,45 @@ angle::Result ContextVk::handleDirtyDescriptorSetsImpl(vk::CommandBuffer *comman

void ContextVk::syncObjectPerfCounters()
{
uint32_t descriptorSetAllocations = 0;
mPerfCounters.descriptorSetAllocations = 0;
mPerfCounters.shaderBuffersDescriptorSetCacheHits = 0;
mPerfCounters.shaderBuffersDescriptorSetCacheMisses = 0;

// ContextVk's descriptor set allocations
ContextVkPerfCounters contextCounters = getAndResetObjectPerfCounters();
for (uint32_t count : contextCounters.descriptorSetsAllocated)
{
descriptorSetAllocations += count;
mPerfCounters.descriptorSetAllocations += count;
}
// UtilsVk's descriptor set allocations
descriptorSetAllocations += mUtils.getAndResetObjectPerfCounters().descriptorSetsAllocated;
mPerfCounters.descriptorSetAllocations +=
mUtils.getAndResetObjectPerfCounters().descriptorSetsAllocated;
// ProgramExecutableVk's descriptor set allocations
const gl::State &state = getState();
const gl::ShaderProgramManager &shadersAndPrograms = state.getShaderProgramManagerForCapture();
const gl::ResourceMap<gl::Program, gl::ShaderProgramID> &programs =
shadersAndPrograms.getProgramsForCaptureAndPerf();
for (const std::pair<GLuint, gl::Program *> &resource : programs)
{
gl::Program *program = resource.second;
if (program->hasLinkingState())
{
continue;
}
ProgramVk *programVk = vk::GetImpl(resource.second);
ProgramExecutablePerfCounters progPerfCounters =
programVk->getExecutable().getAndResetObjectPerfCounters();

for (const uint32_t count : progPerfCounters.descriptorSetsAllocated)
for (uint32_t count : progPerfCounters.descriptorSetAllocations)
{
descriptorSetAllocations += count;
mPerfCounters.descriptorSetAllocations += count;
}

mPerfCounters.shaderBuffersDescriptorSetCacheHits +=
progPerfCounters.descriptorSetCacheHits[DescriptorSetIndex::ShaderResource];
mPerfCounters.shaderBuffersDescriptorSetCacheMisses +=
progPerfCounters.descriptorSetCacheMisses[DescriptorSetIndex::ShaderResource];
}
mPerfCounters.descriptorSetAllocations = descriptorSetAllocations;
}

void ContextVk::updateOverlayOnPresent()
Expand Down Expand Up @@ -2016,6 +2028,22 @@ void ContextVk::updateOverlayOnPresent()
descriptorSetAllocationCount->next();
}

{
gl::RunningGraphWidget *shaderBufferHitRate =
overlay->getRunningGraphWidget(gl::WidgetId::VulkanShaderBufferDSHitRate);
size_t numCacheAccesses = mPerfCounters.shaderBuffersDescriptorSetCacheHits +
mPerfCounters.shaderBuffersDescriptorSetCacheMisses;
if (numCacheAccesses > 0)
{
float hitRateFloat =
static_cast<float>(mPerfCounters.shaderBuffersDescriptorSetCacheHits) /
static_cast<float>(numCacheAccesses);
size_t hitRate = static_cast<size_t>(hitRateFloat * 100.0f);
shaderBufferHitRate->add(hitRate);
shaderBufferHitRate->next();
}
}

{
gl::RunningGraphWidget *dynamicBufferAllocations =
overlay->getRunningGraphWidget(gl::WidgetId::VulkanDynamicBufferAllocations);
Expand Down
47 changes: 42 additions & 5 deletions src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ constexpr bool IsDynamicDescriptor(VkDescriptorType descriptorType)
}

constexpr VkDescriptorType kStorageBufferDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;

DescriptorSetIndex CacheTypeToDescriptorSetIndex(VulkanCacheType cacheType)
{
switch (cacheType)
{
case VulkanCacheType::TextureDescriptors:
return DescriptorSetIndex::Texture;
case VulkanCacheType::ShaderBuffersDescriptors:
return DescriptorSetIndex::ShaderResource;
case VulkanCacheType::UniformsAndXfbDescriptors:
return DescriptorSetIndex::UniformsAndXfb;
case VulkanCacheType::DriverUniformsDescriptors:
return DescriptorSetIndex::Internal;
default:
UNREACHABLE();
return DescriptorSetIndex::InvalidEnum;
}
}
} // namespace

DefaultUniformBlock::DefaultUniformBlock() = default;
Expand Down Expand Up @@ -495,7 +513,7 @@ angle::Result ProgramExecutableVk::allocateDescriptorSetAndGetInfo(
&mDescriptorSets[descriptorSetIndex], newPoolAllocatedOut));
mEmptyDescriptorSets[descriptorSetIndex] = VK_NULL_HANDLE;

++mPerfCounters.descriptorSetsAllocated[descriptorSetIndex];
++mPerfCounters.descriptorSetAllocations[descriptorSetIndex];

return angle::Result::Continue;
}
Expand Down Expand Up @@ -1812,7 +1830,7 @@ angle::Result ProgramExecutableVk::updateDescriptorSets(ContextVk *contextVk,
&mDescriptorPoolBindings[descriptorSetIndex],
&mEmptyDescriptorSets[descriptorSetIndex]));

++mPerfCounters.descriptorSetsAllocated[descriptorSetIndex];
++mPerfCounters.descriptorSetAllocations[descriptorSetIndex];
}
descSet = mEmptyDescriptorSets[descriptorSetIndex];
}
Expand Down Expand Up @@ -1856,7 +1874,7 @@ void ProgramExecutableVk::outputCumulativePerfCounters()

for (DescriptorSetIndex descriptorSetIndex : angle::AllEnums<DescriptorSetIndex>())
{
uint32_t count = mCumulativePerfCounters.descriptorSetsAllocated[descriptorSetIndex];
uint32_t count = mCumulativePerfCounters.descriptorSetAllocations[descriptorSetIndex];
if (count > 0)
{
text << " DescriptorSetIndex " << ToUnderlying(descriptorSetIndex) << ": " << count
Expand All @@ -1883,10 +1901,29 @@ void ProgramExecutableVk::outputCumulativePerfCounters()

ProgramExecutablePerfCounters ProgramExecutableVk::getAndResetObjectPerfCounters()
{
mCumulativePerfCounters.descriptorSetsAllocated += mPerfCounters.descriptorSetsAllocated;
mUniformsAndXfbDescriptorsCache.accumulateCacheStats(this);
mTextureDescriptorsCache.accumulateCacheStats(this);
mShaderBufferDescriptorsCache.accumulateCacheStats(this);

mCumulativePerfCounters.descriptorSetAllocations += mPerfCounters.descriptorSetAllocations;
mCumulativePerfCounters.descriptorSetCacheHits += mPerfCounters.descriptorSetCacheHits;
mCumulativePerfCounters.descriptorSetCacheMisses += mPerfCounters.descriptorSetCacheMisses;

ProgramExecutablePerfCounters counters = mPerfCounters;
mPerfCounters.descriptorSetsAllocated = {};
mPerfCounters.descriptorSetAllocations = {};
mPerfCounters.descriptorSetCacheHits = {};
mPerfCounters.descriptorSetCacheMisses = {};
return counters;
}

void ProgramExecutableVk::accumulateCacheStats(VulkanCacheType cacheType,
const CacheStats &cacheStats)
{
DescriptorSetIndex dsIndex = CacheTypeToDescriptorSetIndex(cacheType);

mPerfCounters.descriptorSetCacheHits[dsIndex] +=
static_cast<uint32_t>(cacheStats.getHitCount());
mPerfCounters.descriptorSetCacheMisses[dsIndex] +=
static_cast<uint32_t>(cacheStats.getMissCount());
}
} // namespace rx
5 changes: 4 additions & 1 deletion src/libANGLE/renderer/vulkan/ProgramExecutableVk.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ using DescriptorSetCountList = angle::PackedEnumMap<DescriptorSetIndex, uint32_t

struct ProgramExecutablePerfCounters
{
DescriptorSetCountList descriptorSetsAllocated;
DescriptorSetCountList descriptorSetAllocations;
DescriptorSetCountList descriptorSetCacheHits;
DescriptorSetCountList descriptorSetCacheMisses;
};

class ProgramExecutableVk
Expand Down Expand Up @@ -190,6 +192,7 @@ class ProgramExecutableVk
return mUniformBufferDescriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
}

void accumulateCacheStats(VulkanCacheType cacheType, const CacheStats &cacheStats);
ProgramExecutablePerfCounters getAndResetObjectPerfCounters();

private:
Expand Down
15 changes: 9 additions & 6 deletions src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3553,7 +3553,7 @@ GraphicsPipelineCache::~GraphicsPipelineCache()

void GraphicsPipelineCache::destroy(RendererVk *rendererVk)
{
rendererVk->accumulateCacheStats(VulkanCacheType::GraphicsPipeline, mCacheStats);
accumulateCacheStats(rendererVk);

VkDevice device = rendererVk->getDevice();

Expand Down Expand Up @@ -3696,7 +3696,7 @@ PipelineLayoutCache::~PipelineLayoutCache()

void PipelineLayoutCache::destroy(RendererVk *rendererVk)
{
rendererVk->accumulateCacheStats(VulkanCacheType::PipelineLayout, mCacheStats);
accumulateCacheStats(rendererVk);

VkDevice device = rendererVk->getDevice();

Expand Down Expand Up @@ -3904,25 +3904,28 @@ angle::Result SamplerCache::getSampler(ContextVk *contextVk,
// DriverUniformsDescriptorSetCache implementation.
void DriverUniformsDescriptorSetCache::destroy(RendererVk *rendererVk)
{
rendererVk->accumulateCacheStats(VulkanCacheType::DescriptorSet, mCacheStats);
accumulateCacheStats(rendererVk);
mPayload.clear();
}

// DescriptorSetCache implementation.
template <typename key, VulkanCacheType cacheType>
void DescriptorSetCache<key, cacheType>::destroy(RendererVk *rendererVk)
template <typename Key, VulkanCacheType CacheType>
void DescriptorSetCache<Key, CacheType>::destroy(RendererVk *rendererVk)
{
rendererVk->accumulateCacheStats(cacheType, mCacheStats);
this->accumulateCacheStats(rendererVk);
mPayload.clear();
}

// RendererVk's methods are not accessible in vk_cache_utils.h
// Below declarations are needed to avoid linker errors.
// Unclear why Clang warns about weak vtables in this case.
ANGLE_DISABLE_WEAK_TEMPLATE_VTABLES_WARNING
template class DescriptorSetCache<vk::TextureDescriptorDesc, VulkanCacheType::TextureDescriptors>;

template class DescriptorSetCache<vk::UniformsAndXfbDescriptorDesc,
VulkanCacheType::UniformsAndXfbDescriptors>;

template class DescriptorSetCache<vk::ShaderBuffersDescriptorDesc,
VulkanCacheType::ShaderBuffersDescriptors>;
ANGLE_REENABLE_WEAK_TEMPLATE_VTABLES_WARNING
} // namespace rx
Loading

0 comments on commit ccc0fba

Please sign in to comment.