diff --git a/BUILD.gn b/BUILD.gn index b8057d5b4..f65500307 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -606,6 +606,9 @@ config("libANGLE_config") { if (angle_enable_overlay) { defines += [ "ANGLE_ENABLE_OVERLAY=1" ] } + if (angle_enable_perf_counter_output) { + defines += [ "ANGLE_ENABLE_PERF_COUNTER_OUTPUT=1" ] + } } angle_source_set("libANGLE_headers") { diff --git a/gni/angle.gni b/gni/angle.gni index fc3001fa7..289d8bafe 100644 --- a/gni/angle.gni +++ b/gni/angle.gni @@ -131,6 +131,9 @@ declare_args() { # Disable overlay by default angle_enable_overlay = false + + # Disable performance counter output by default + angle_enable_perf_counter_output = false } if (!defined(angle_zlib_compression_utils_dir)) { diff --git a/scripts/code_generation_hashes/overlay_widgets.json b/scripts/code_generation_hashes/overlay_widgets.json index 696b17b60..6887216a9 100644 --- a/scripts/code_generation_hashes/overlay_widgets.json +++ b/scripts/code_generation_hashes/overlay_widgets.json @@ -1,10 +1,10 @@ { "src/libANGLE/Overlay_autogen.cpp": - "6c9c7df59562390505222145c1f32277", + "849f447a220cb0ce00a41f99db179a6b", "src/libANGLE/Overlay_autogen.h": - "03ac72d8286f1f933696fa3dabb75eb1", + "4f29dd0e9c2030b98b396fdf03eaeb29", "src/libANGLE/gen_overlay_widgets.py": "f4395481db010c82af2e2981353e8592", "src/libANGLE/overlay_widgets.json": - "dd9d2a72035e754bbc5f614410e76df1" + "93205f3d9585228428bc62463f478dc6" } \ No newline at end of file diff --git a/src/libANGLE/FrameCapture.cpp b/src/libANGLE/FrameCapture.cpp index 844194853..22bed01cf 100644 --- a/src/libANGLE/FrameCapture.cpp +++ b/src/libANGLE/FrameCapture.cpp @@ -2798,7 +2798,7 @@ void CaptureMidExecutionSetup(const gl::Context *context, const gl::ResourceMap &shaders = shadersAndPrograms.getShadersForCapture(); const gl::ResourceMap &programs = - shadersAndPrograms.getProgramsForCapture(); + shadersAndPrograms.getProgramsForCaptureAndPerf(); // Capture Program binary state. Use max ID as a temporary shader ID. gl::ShaderProgramID tempShaderID = {resourceTracker->getMaxShaderPrograms()}; diff --git a/src/libANGLE/OverlayWidgets.cpp b/src/libANGLE/OverlayWidgets.cpp index 708f33a8a..22c8972d0 100644 --- a/src/libANGLE/OverlayWidgets.cpp +++ b/src/libANGLE/OverlayWidgets.cpp @@ -300,10 +300,10 @@ void AppendWidgetDataHelper::AppendRunningHistogramCommon(const overlay::Widget OverlayWidgetCounts *widgetCounts, FormatHistogramTitleFunc formatFunc) { - const overlay::RunningHistogram *secondaryCommandBufferPoolWaste = + const overlay::RunningHistogram *runningHistogram = static_cast(widget); - std::vector histogram = CreateHistogram(secondaryCommandBufferPoolWaste->runningValues); + std::vector histogram = CreateHistogram(runningHistogram->runningValues); auto peakRangeIt = std::max_element(histogram.rbegin(), histogram.rend()); const size_t peakRangeValue = *peakRangeIt; const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]); @@ -320,8 +320,8 @@ void AppendWidgetDataHelper::AppendRunningHistogramCommon(const overlay::Widget size_t maxValueRange = std::distance(maxValueIter, histogram.rend() - 1); std::string text = formatFunc(peakRange, maxValueRange, histogram.size()); - AppendTextCommon(&secondaryCommandBufferPoolWaste->description, imageExtent, text, - textWidget, widgetCounts); + AppendTextCommon(&runningHistogram->description, imageExtent, text, textWidget, + widgetCounts); } } @@ -431,6 +431,21 @@ void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(const overlay:: AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); } +void AppendWidgetDataHelper::AppendVulkanDescriptorSetAllocations(const overlay::Widget *widget, + const gl::Extents &imageExtent, + TextWidgetData *textWidget, + GraphWidgetData *graphWidget, + OverlayWidgetCounts *widgetCounts) +{ + auto format = [](size_t maxValue) { + std::ostringstream text; + text << "Descriptor Set Allocations (Max: " << maxValue << ")"; + return text.str(); + }; + + AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format); +} + std::ostream &AppendWidgetDataHelper::OutputPerSecond(std::ostream &out, const overlay::PerSecond *perSecond) { diff --git a/src/libANGLE/Overlay_autogen.cpp b/src/libANGLE/Overlay_autogen.cpp index 7814962e2..8c8440d50 100644 --- a/src/libANGLE/Overlay_autogen.cpp +++ b/src/libANGLE/Overlay_autogen.cpp @@ -274,6 +274,49 @@ void Overlay::initOverlayWidgets() widget->description.color[3] = 1.0f; } } + + { + RunningGraph *widget = new RunningGraph(60); + { + const int32_t fontSize = GetFontSize(0, kLargeFont); + const int32_t offsetX = -50; + const int32_t offsetY = 250; + const int32_t width = 6 * static_cast(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::VulkanDescriptorSetAllocations].reset(widget); + { + const int32_t fontSize = GetFontSize(kFontLayerSmall, kLargeFont); + const int32_t offsetX = + mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations]->coords[0]; + const int32_t offsetY = + mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations]->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; + } + } } } // namespace gl diff --git a/src/libANGLE/Overlay_autogen.h b/src/libANGLE/Overlay_autogen.h index e3b41a9f3..c8953fefe 100644 --- a/src/libANGLE/Overlay_autogen.h +++ b/src/libANGLE/Overlay_autogen.h @@ -26,6 +26,8 @@ enum class WidgetId VulkanSecondaryCommandBufferPoolWaste, // Number of Descriptor Set writes in a frame (Count). VulkanWriteDescriptorSetCount, + // Descriptor Set Allocations. + VulkanDescriptorSetAllocations, InvalidEnum, EnumCount = InvalidEnum, @@ -39,6 +41,7 @@ enum class WidgetId PROC(VulkanRenderPassCount) \ PROC(VulkanRenderPassBufferCount) \ PROC(VulkanSecondaryCommandBufferPoolWaste) \ - PROC(VulkanWriteDescriptorSetCount) + PROC(VulkanWriteDescriptorSetCount) \ + PROC(VulkanDescriptorSetAllocations) } // namespace gl diff --git a/src/libANGLE/ResourceManager.h b/src/libANGLE/ResourceManager.h index 4e62c4290..e58cd9d86 100644 --- a/src/libANGLE/ResourceManager.h +++ b/src/libANGLE/ResourceManager.h @@ -164,9 +164,12 @@ class ShaderProgramManager : public ResourceManagerBase return mPrograms.query(handle); } - // For capture only. + // For capture and performance counters only. const ResourceMap &getShadersForCapture() const { return mShaders; } - const ResourceMap &getProgramsForCapture() const { return mPrograms; } + const ResourceMap &getProgramsForCaptureAndPerf() const + { + return mPrograms; + } protected: ~ShaderProgramManager() override; diff --git a/src/libANGLE/frame_capture_utils.cpp b/src/libANGLE/frame_capture_utils.cpp index 5f607d2bf..54ccd53ff 100644 --- a/src/libANGLE/frame_capture_utils.cpp +++ b/src/libANGLE/frame_capture_utils.cpp @@ -991,7 +991,7 @@ Result SerializeContext(gl::BinaryOutputStream *bos, const gl::Context *context) SerializeShader(bos, shaderPtr); } const gl::ResourceMap &programManager = - shaderProgramManager.getProgramsForCapture(); + shaderProgramManager.getProgramsForCaptureAndPerf(); for (const auto &program : programManager) { gl::Program *programPtr = program.second; diff --git a/src/libANGLE/overlay_widgets.json b/src/libANGLE/overlay_widgets.json index 69ae103c8..bb914c927 100644 --- a/src/libANGLE/overlay_widgets.json +++ b/src/libANGLE/overlay_widgets.json @@ -116,6 +116,22 @@ "font": "small", "length": 40 } + }, + { + "name": "VulkanDescriptorSetAllocations", + "comment": "Descriptor Set Allocations.", + "type": "RunningGraph(60)", + "color": [255, 0, 75, 200], + "coords": [-50, 250], + "bar_width": 6, + "height": 100, + "description": { + "color": [255, 0, 75, 255], + "coords": ["VulkanDescriptorSetAllocations.left.align", + "VulkanDescriptorSetAllocations.top.adjacent"], + "font": "small", + "length": 40 + } } ] } diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp index 4c13cb72f..1fccf9318 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -702,6 +702,7 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk mGpuClockSync{std::numeric_limits::max(), std::numeric_limits::max()}, mGpuEventTimestampOrigin(0), mPerfCounters{}, + mObjectPerfCounters{}, mContextPriority(renderer->getDriverPriority(GetContextPriority(state))), mCurrentIndirectBuffer(nullptr), mShareGroupVk(vk::GetImpl(state.getShareGroup())) @@ -784,12 +785,16 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk mDescriptorBufferInfos.reserve(kDescriptorBufferInfosInitialSize); mDescriptorImageInfos.reserve(kDescriptorImageInfosInitialSize); mWriteDescriptorSets.reserve(kDescriptorWriteInfosInitialSize); + + mObjectPerfCounters.descriptorSetsAllocated.fill(0); } ContextVk::~ContextVk() = default; void ContextVk::onDestroy(const gl::Context *context) { + outputCumulativePerfCounters(); + // Remove context from the share group mShareGroupVk->getShareContextSet()->erase(this); @@ -1778,6 +1783,42 @@ void ContextVk::updateOverlayOnPresent() mPerfCounters.writeDescriptorSets = 0; } + + { + uint32_t descriptorSetAllocations = 0; + + // ContextVk's descriptor set allocations + for (const uint32_t count : mObjectPerfCounters.descriptorSetsAllocated) + { + descriptorSetAllocations += count; + } + // UtilsVk's descriptor set allocations + descriptorSetAllocations += mUtils.getObjectPerfCounters().descriptorSetsAllocated; + // ProgramExecutableVk's descriptor set allocations + const gl::State &state = getState(); + const gl::ShaderProgramManager &shadersAndPrograms = + state.getShaderProgramManagerForCapture(); + const gl::ResourceMap &programs = + shadersAndPrograms.getProgramsForCaptureAndPerf(); + for (const std::pair &resource : programs) + { + ProgramVk *programVk = vk::GetImpl(resource.second); + ProgramExecutableVk::PerfCounters progPerfCounters = + programVk->getExecutable().getObjectPerfCounters(); + + for (const uint32_t count : progPerfCounters.descriptorSetsAllocated) + { + descriptorSetAllocations += count; + } + } + + gl::RunningGraphWidget *descriptorSetAllocationCount = + overlay->getRunningGraphWidget(gl::WidgetId::VulkanDescriptorSetAllocations); + descriptorSetAllocationCount->add(descriptorSetAllocations - + mPerfCounters.descriptorSetAllocations); + descriptorSetAllocationCount->next(); + mPerfCounters.descriptorSetAllocations = descriptorSetAllocations; + } } void ContextVk::addOverlayUsedBuffersCount(vk::CommandBufferHelper *commandBuffer) @@ -4077,6 +4118,7 @@ angle::Result ContextVk::updateDriverUniformsDescriptorSet( ANGLE_TRY(mDriverUniformsDescriptorPools[pipelineType].allocateSetsAndGetInfo( this, driverUniforms->descriptorSetLayout.get().ptr(), 1, &driverUniforms->descriptorPoolBinding, &driverUniforms->descriptorSet, &newPoolAllocated)); + mObjectPerfCounters.descriptorSetsAllocated[ToUnderlying(pipelineType)]++; // Clear descriptor set cache. It may no longer be valid. if (newPoolAllocated) @@ -5340,4 +5382,27 @@ bool ContextVk::shouldSwitchToReadOnlyDepthFeedbackLoopMode(const gl::Context *c texture->isBoundToFramebuffer(mDrawFramebuffer->getState().getFramebufferSerial()) && !mDrawFramebuffer->isReadOnlyDepthFeedbackLoopMode(); } + +// Requires that trace is enabled to see the output, which is supported with is_debug=true +void ContextVk::outputCumulativePerfCounters() +{ + if (!vk::kOutputCumulativePerfCounters) + { + return; + } + + { + INFO() << "Context Descriptor Set Allocations: "; + + for (size_t pipelineType = 0; + pipelineType < mObjectPerfCounters.descriptorSetsAllocated.size(); ++pipelineType) + { + uint32_t count = mObjectPerfCounters.descriptorSetsAllocated[pipelineType]; + if (count > 0) + { + INFO() << " PipelineType " << pipelineType << ": " << count; + } + } + } +} } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h index 64284e21f..7718f5cec 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/src/libANGLE/renderer/vulkan/ContextVk.h @@ -768,6 +768,14 @@ class ContextVk : public ContextImpl, public vk::Context double cpuTimestampS; }; + // Performance Counters specific to this object type + using DescriptorSetList = + std::array; + struct PerfCounters + { + DescriptorSetList descriptorSetsAllocated; + }; + class ScopedDescriptorSetUpdates; angle::Result setupDraw(const gl::Context *context, @@ -989,6 +997,8 @@ class ContextVk : public ContextImpl, public vk::Context bool shouldSwitchToReadOnlyDepthFeedbackLoopMode(const gl::Context *context, gl::Texture *texture) const; + void outputCumulativePerfCounters(); + std::array mGraphicsDirtyBitHandlers; std::array mComputeDirtyBitHandlers; @@ -1157,6 +1167,7 @@ class ContextVk : public ContextImpl, public vk::Context // A mix of per-frame and per-run counters. vk::PerfCounters mPerfCounters; + PerfCounters mObjectPerfCounters; gl::State::DirtyBits mPipelineDirtyBitsMask; diff --git a/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp b/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp index 987d50dc4..d18f35776 100644 --- a/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp +++ b/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp @@ -182,10 +182,14 @@ ProgramExecutableVk::ProgramExecutableVk() mNumDefaultUniformDescriptors(0), mDynamicBufferOffsets{}, mProgram(nullptr), - mProgramPipeline(nullptr) + mProgramPipeline(nullptr), + mObjectPerfCounters{} {} -ProgramExecutableVk::~ProgramExecutableVk() = default; +ProgramExecutableVk::~ProgramExecutableVk() +{ + outputCumulativePerfCounters(); +} void ProgramExecutableVk::reset(ContextVk *contextVk) { @@ -424,6 +428,8 @@ angle::Result ProgramExecutableVk::allocateDescriptorSetAndGetInfo( &mDescriptorSets[ToUnderlying(descriptorSetIndex)], newPoolAllocatedOut)); mEmptyDescriptorSets[ToUnderlying(descriptorSetIndex)] = VK_NULL_HANDLE; + ++mObjectPerfCounters.descriptorSetsAllocated[ToUnderlying(descriptorSetIndex)]; + return angle::Result::Continue; } @@ -1561,6 +1567,8 @@ angle::Result ProgramExecutableVk::updateDescriptorSets(ContextVk *contextVk, contextVk, descriptorSetLayout.ptr(), 1, &mDescriptorPoolBindings[descriptorSetIndex], &mEmptyDescriptorSets[descriptorSetIndex])); + + ++mObjectPerfCounters.descriptorSetsAllocated[descriptorSetIndex]; } descSet = mEmptyDescriptorSets[descriptorSetIndex]; } @@ -1582,4 +1590,44 @@ angle::Result ProgramExecutableVk::updateDescriptorSets(ContextVk *contextVk, return angle::Result::Continue; } +// Requires that trace is enabled to see the output, which is supported with is_debug=true +void ProgramExecutableVk::outputCumulativePerfCounters() +{ + if (!vk::kOutputCumulativePerfCounters) + { + return; + } + + { + std::ostringstream text; + + for (size_t descriptorSetIndex = 0; + descriptorSetIndex < mObjectPerfCounters.descriptorSetsAllocated.size(); + ++descriptorSetIndex) + { + uint32_t count = mObjectPerfCounters.descriptorSetsAllocated[descriptorSetIndex]; + if (count > 0) + { + text << " DescriptorSetIndex " << descriptorSetIndex << ": " << count << "\n"; + } + } + + // Only output information for programs that allocated descriptor sets. + std::string textStr = text.str(); + if (!textStr.empty()) + { + INFO() << "ProgramExecutable: " << this << ":"; + + // Output each descriptor set allocation on a single line, so they're prefixed with the + // INFO information (file, line number, etc.). + // https://stackoverflow.com/a/12514641 + std::istringstream iss(textStr); + for (std::string line; std::getline(iss, line);) + { + INFO() << line; + } + } + } +} + } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h b/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h index 2d87510f7..87b173ed5 100644 --- a/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h +++ b/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h @@ -168,6 +168,15 @@ class ProgramExecutableVk mProgramPipeline = pipeline; } + using DescriptorSetCountList = std::array; + // Performance and resource counters. + struct PerfCounters + { + DescriptorSetCountList descriptorSetsAllocated; + }; + + const PerfCounters getObjectPerfCounters() const { return mObjectPerfCounters; } + private: friend class ProgramVk; friend class ProgramPipelineVk; @@ -224,6 +233,8 @@ class ProgramExecutableVk DescriptorSetIndex descriptorSetIndex, VkDescriptorSetLayout descriptorSetLayout); + void outputCumulativePerfCounters(); + // Descriptor sets for uniform blocks and textures for this program. vk::DescriptorSetLayoutArray mDescriptorSets; vk::DescriptorSetLayoutArray mEmptyDescriptorSets; @@ -260,6 +271,8 @@ class ProgramExecutableVk ProgramVk *mProgram; ProgramPipelineVk *mProgramPipeline; + + PerfCounters mObjectPerfCounters; }; } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/UtilsVk.cpp b/src/libANGLE/renderer/vulkan/UtilsVk.cpp index 27584b8c4..75ba91542 100644 --- a/src/libANGLE/renderer/vulkan/UtilsVk.cpp +++ b/src/libANGLE/renderer/vulkan/UtilsVk.cpp @@ -15,6 +15,7 @@ #include "libANGLE/renderer/vulkan/GlslangWrapperVk.h" #include "libANGLE/renderer/vulkan/RenderTargetVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h" +#include "libANGLE/renderer/vulkan/vk_utils.h" namespace rx { @@ -530,7 +531,7 @@ uint32_t UtilsVk::GetGenerateMipmapMaxLevels(ContextVk *contextVk) : kGenerateMipmapMaxLevels; } -UtilsVk::UtilsVk() = default; +UtilsVk::UtilsVk() : mObjectPerfCounters{} {} UtilsVk::~UtilsVk() = default; @@ -538,6 +539,8 @@ void UtilsVk::destroy(RendererVk *renderer) { VkDevice device = renderer->getDevice(); + outputCumulativePerfCounters(); + for (Function f : angle::AllEnums()) { for (auto &descriptorSetLayout : mDescriptorSetLayouts[f]) @@ -2632,6 +2635,9 @@ angle::Result UtilsVk::allocateDescriptorSet(ContextVk *contextVk, .ptr(), 1, bindingOut, descriptorSetOut)); bindingOut->get().updateSerial(contextVk->getCurrentQueueSerial()); + + mObjectPerfCounters.descriptorSetsAllocated++; + return angle::Result::Continue; } @@ -2647,4 +2653,15 @@ UtilsVk::ClearFramebufferParameters::ClearFramebufferParameters() depthStencilClearValue{} {} +// Requires that trace is enabled to see the output, which is supported with is_debug=true +void UtilsVk::outputCumulativePerfCounters() +{ + if (!vk::kOutputCumulativePerfCounters) + { + return; + } + + INFO() << "Utils Descriptor Set Allocations: " << mObjectPerfCounters.descriptorSetsAllocated; +} + } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/UtilsVk.h b/src/libANGLE/renderer/vulkan/UtilsVk.h index df4a7ef46..fd097bc71 100644 --- a/src/libANGLE/renderer/vulkan/UtilsVk.h +++ b/src/libANGLE/renderer/vulkan/UtilsVk.h @@ -166,6 +166,12 @@ class UtilsVk : angle::NonCopyable bool unresolveStencil; }; + struct PerfCounters + { + // Total descriptor set allocations for all UtilsVk::Functions + uint32_t descriptorSetsAllocated; + }; + // Based on the maximum number of levels in GenerateMipmap.comp. static constexpr uint32_t kGenerateMipmapMaxLevels = 6; static uint32_t GetGenerateMipmapMaxLevels(ContextVk *contextVk); @@ -262,6 +268,8 @@ class UtilsVk : angle::NonCopyable const vk::ImageView *destView, const OverlayDrawParameters ¶ms); + const PerfCounters getObjectPerfCounters() const { return mObjectPerfCounters; } + private: ANGLE_ENABLE_STRUCT_PADDING_WARNINGS @@ -502,6 +510,8 @@ class UtilsVk : angle::NonCopyable vk::RefCountedDescriptorPoolBinding *bindingOut, VkDescriptorSet *descriptorSetOut); + void outputCumulativePerfCounters(); + angle::PackedEnumMap mDescriptorSetLayouts; angle::PackedEnumMap> mPipelineLayouts; angle::PackedEnumMap mDescriptorPools; @@ -531,6 +541,8 @@ class UtilsVk : angle::NonCopyable vk::Sampler mPointSampler; vk::Sampler mLinearSampler; + + PerfCounters mObjectPerfCounters; }; } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/vk_utils.h b/src/libANGLE/renderer/vulkan/vk_utils.h index 56363e393..88c882ba3 100644 --- a/src/libANGLE/renderer/vulkan/vk_utils.h +++ b/src/libANGLE/renderer/vulkan/vk_utils.h @@ -70,6 +70,7 @@ namespace rx { class DisplayVk; class ImageVk; +class ProgramExecutableVk; class RenderTargetVk; class RendererVk; class RenderPassCache; @@ -184,7 +185,7 @@ class Context : angle::NonCopyable #if ANGLE_USE_CUSTOM_VULKAN_CMD_BUFFERS using CommandBuffer = priv::SecondaryCommandBuffer; #else -using CommandBuffer = priv::CommandBuffer; +using CommandBuffer = priv::CommandBuffer; #endif using PrimaryCommandBuffer = priv::CommandBuffer; @@ -781,6 +782,12 @@ class ResourceSerialFactory final : angle::NonCopyable std::atomic mCurrentUniqueSerial; }; +#if defined(ANGLE_ENABLE_PERF_COUNTER_OUTPUT) +constexpr bool kOutputCumulativePerfCounters = ANGLE_ENABLE_PERF_COUNTER_OUTPUT; +#else +constexpr bool kOutputCumulativePerfCounters = false; +#endif + // Performance and resource counters. struct RenderPassPerfCounters { @@ -823,6 +830,7 @@ struct PerfCounters uint32_t depthAttachmentResolves; uint32_t stencilAttachmentResolves; uint32_t readOnlyDepthStencilRenderPasses; + uint32_t descriptorSetAllocations; }; // A Vulkan image level index.