From a956162cc04348cd6685f739096b6e344170cb54 Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Tue, 1 Mar 2022 13:05:29 -0500 Subject: [PATCH] Vulkan: Expose performance counters via extension. This CL rewrites the Vulkan perf counters test to work in the angle_end2end_test suite using the newly exposed AMD extension. Note that we implement only a subset of the extension. Instead of generating monitors and starting/stopping them we simply read back all performance counter data at once using the special montior value "0". The CL also enables these tests on SwiftShader. Bug: angleproject:4918 Change-Id: I5d8f6eecb1ccff448657cbdb65b51a225dfb90c0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3497538 Reviewed-by: Charlie Lao Reviewed-by: Yuxin Hu Commit-Queue: Jamie Madill --- src/common/angleutils.cpp | 64 ++ src/common/angleutils.h | 83 +++ src/libANGLE/Context.cpp | 187 +++++- src/libANGLE/Context.h | 2 + src/libANGLE/ErrorStrings.h | 3 + .../capture/capture_gles_ext_params.cpp | 18 +- src/libANGLE/renderer/ContextImpl.cpp | 6 + src/libANGLE/renderer/ContextImpl.h | 3 + src/libANGLE/renderer/vulkan/ContextVk.cpp | 33 + src/libANGLE/renderer/vulkan/ContextVk.h | 9 +- .../renderer/vulkan/FramebufferVk.cpp | 2 +- .../renderer/vulkan/vk_cache_utils.cpp | 2 +- src/libANGLE/renderer/vulkan/vk_utils.h | 37 - src/libANGLE/validationESEXT.cpp | 90 ++- src/tests/angle_end2end_tests.gni | 1 + .../angle_end2end_tests_expectations.txt | 2 + src/tests/angle_white_box_tests.gni | 1 - .../capture_replay_expectations.txt | 2 + .../gl_tests/VulkanPerformanceCounterTest.cpp | 632 ++++++++++-------- 19 files changed, 842 insertions(+), 335 deletions(-) diff --git a/src/common/angleutils.cpp b/src/common/angleutils.cpp index 7de140ab1..2b69f66d7 100644 --- a/src/common/angleutils.cpp +++ b/src/common/angleutils.cpp @@ -45,6 +45,70 @@ void SaveFileHelper::write(const uint8_t *data, size_t size) mOfs.write(reinterpret_cast(data), size); } +// AMD_performance_monitor helpers. + +PerfMonitorCounter::PerfMonitorCounter() = default; + +PerfMonitorCounter::~PerfMonitorCounter() = default; + +PerfMonitorCounterGroup::PerfMonitorCounterGroup() = default; + +PerfMonitorCounterGroup::~PerfMonitorCounterGroup() = default; + +uint32_t GetPerfMonitorCounterIndex(const PerfMonitorCounters &counters, const std::string &name) +{ + for (uint32_t counterIndex = 0; counterIndex < static_cast(counters.size()); + ++counterIndex) + { + if (counters[counterIndex].name == name) + { + return counterIndex; + } + } + + return std::numeric_limits::max(); +} + +uint32_t GetPerfMonitorCounterGroupIndex(const PerfMonitorCounterGroups &groups, + const std::string &name) +{ + for (uint32_t groupIndex = 0; groupIndex < static_cast(groups.size()); ++groupIndex) + { + if (groups[groupIndex].name == name) + { + return groupIndex; + } + } + + return std::numeric_limits::max(); +} + +const PerfMonitorCounter &GetPerfMonitorCounter(const PerfMonitorCounters &counters, + const std::string &name) +{ + return GetPerfMonitorCounter(const_cast(counters), name); +} + +PerfMonitorCounter &GetPerfMonitorCounter(PerfMonitorCounters &counters, const std::string &name) +{ + uint32_t counterIndex = GetPerfMonitorCounterIndex(counters, name); + ASSERT(counterIndex < static_cast(counters.size())); + return counters[counterIndex]; +} + +const PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(const PerfMonitorCounterGroups &groups, + const std::string &name) +{ + return GetPerfMonitorCounterGroup(const_cast(groups), name); +} + +PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(PerfMonitorCounterGroups &groups, + const std::string &name) +{ + uint32_t groupIndex = GetPerfMonitorCounterGroupIndex(groups, name); + ASSERT(groupIndex < static_cast(groups.size())); + return groups[groupIndex]; +} } // namespace angle std::string ArrayString(unsigned int i) diff --git a/src/common/angleutils.h b/src/common/angleutils.h index 0501ff078..dd70f4f4f 100644 --- a/src/common/angleutils.h +++ b/src/common/angleutils.h @@ -89,6 +89,89 @@ struct SaveFileHelper std::string mFilePath; }; +// AMD_performance_monitor helpers. +struct PerfMonitorCounter +{ + PerfMonitorCounter(); + ~PerfMonitorCounter(); + + std::string name; + uint32_t value; +}; +using PerfMonitorCounters = std::vector; + +struct PerfMonitorCounterGroup +{ + PerfMonitorCounterGroup(); + ~PerfMonitorCounterGroup(); + + std::string name; + PerfMonitorCounters counters; +}; +using PerfMonitorCounterGroups = std::vector; + +uint32_t GetPerfMonitorCounterIndex(const PerfMonitorCounters &counters, const std::string &name); +const PerfMonitorCounter &GetPerfMonitorCounter(const PerfMonitorCounters &counters, + const std::string &name); +PerfMonitorCounter &GetPerfMonitorCounter(PerfMonitorCounters &counters, const std::string &name); +uint32_t GetPerfMonitorCounterGroupIndex(const PerfMonitorCounterGroups &groups, + const std::string &name); +const PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(const PerfMonitorCounterGroups &groups, + const std::string &name); +PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(PerfMonitorCounterGroups &groups, + const std::string &name); + +struct PerfMonitorTriplet +{ + uint32_t group; + uint32_t counter; + uint32_t value; +}; + +#define ANGLE_VK_PERF_COUNTERS_X(FN) \ + FN(primaryBuffers) \ + FN(renderPasses) \ + FN(writeDescriptorSets) \ + FN(flushedOutsideRenderPassCommandBuffers) \ + FN(resolveImageCommands) \ + FN(depthClears) \ + FN(depthLoads) \ + FN(depthStores) \ + FN(stencilClears) \ + FN(stencilLoads) \ + FN(stencilStores) \ + FN(colorAttachmentUnresolves) \ + FN(depthAttachmentUnresolves) \ + FN(stencilAttachmentUnresolves) \ + FN(colorAttachmentResolves) \ + FN(depthAttachmentResolves) \ + FN(stencilAttachmentResolves) \ + FN(readOnlyDepthStencilRenderPasses) \ + FN(descriptorSetAllocations) \ + FN(descriptorSetCacheTotalSize) \ + FN(descriptorSetCacheKeySizeBytes) \ + FN(uniformsAndXfbDescriptorSetCacheHits) \ + FN(uniformsAndXfbDescriptorSetCacheMisses) \ + FN(uniformsAndXfbDescriptorSetCacheTotalSize) \ + FN(textureDescriptorSetCacheHits) \ + FN(textureDescriptorSetCacheMisses) \ + FN(textureDescriptorSetCacheTotalSize) \ + FN(shaderBuffersDescriptorSetCacheHits) \ + FN(shaderBuffersDescriptorSetCacheMisses) \ + FN(shaderBuffersDescriptorSetCacheTotalSize) \ + FN(buffersGhosted) \ + FN(vertexArraySyncStateCalls) \ + FN(allocateNewBufferBlockCalls) + +#define ANGLE_DECLARE_PERF_COUNTER(COUNTER) uint32_t COUNTER; + +struct VulkanPerfCounters +{ + ANGLE_VK_PERF_COUNTERS_X(ANGLE_DECLARE_PERF_COUNTER) +}; + +#undef ANGLE_DECLARE_PERF_COUNTER + } // namespace angle template diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp index b66ac27f6..f4277504e 100755 --- a/src/libANGLE/Context.cpp +++ b/src/libANGLE/Context.cpp @@ -331,6 +331,33 @@ bool GetSaveAndRestoreState(const egl::AttributeMap &attribs) { return (attribs.get(EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE, EGL_FALSE) == EGL_TRUE); } + +void GetPerfMonitorString(const std::string &name, + GLsizei bufSize, + GLsizei *length, + GLchar *stringOut) +{ + GLsizei numCharsWritten = std::min(bufSize, static_cast(name.size())); + + if (length) + { + if (bufSize == 0) + { + *length = static_cast(name.size()); + } + else + { + // Excludes null terminator. + ASSERT(numCharsWritten > 0); + *length = numCharsWritten - 1; + } + } + + if (stringOut) + { + memcpy(stringOut, name.c_str(), numCharsWritten); + } +} } // anonymous namespace #if defined(ANGLE_PLATFORM_APPLE) @@ -3717,6 +3744,9 @@ Extensions Context::generateSupportedExtensions() const // Always enabled. Will return a default string if capture is not enabled. supportedExtensions.getSerializedContextStringANGLE = true; + // Performance counter queries are always supported. Different groups exist on each back-end. + supportedExtensions.performanceMonitorAMD = true; + return supportedExtensions; } @@ -9385,38 +9415,176 @@ void Context::deletePerfMonitors(GLsizei n, GLuint *monitors) {} void Context::endPerfMonitor(GLuint monitor) {} -void Context::genPerfMonitors(GLsizei n, GLuint *monitors) {} +void Context::genPerfMonitors(GLsizei n, GLuint *monitors) +{ + for (GLsizei monitorIndex = 0; monitorIndex < n; ++monitorIndex) + { + monitors[n] = static_cast(monitorIndex); + } +} void Context::getPerfMonitorCounterData(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) -{} +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + GLint byteCount = 0; + switch (pname) + { + case GL_PERFMON_RESULT_AVAILABLE_AMD: + { + *data = GL_TRUE; + byteCount += sizeof(GLuint); + break; + } + case GL_PERFMON_RESULT_SIZE_AMD: + { + GLuint resultSize = 0; + for (const PerfMonitorCounterGroup &group : perfMonitorGroups) + { + resultSize += sizeof(PerfMonitorTriplet) * group.counters.size(); + } + *data = resultSize; + byteCount += sizeof(GLuint); + break; + } + case GL_PERFMON_RESULT_AMD: + { + PerfMonitorTriplet *resultsOut = reinterpret_cast(data); + GLsizei maxResults = dataSize / (3 * sizeof(GLuint)); + GLsizei resultCount = 0; + for (size_t groupIndex = 0; + groupIndex < perfMonitorGroups.size() && resultCount < maxResults; ++groupIndex) + { + const PerfMonitorCounterGroup &group = perfMonitorGroups[groupIndex]; + for (size_t counterIndex = 0; + counterIndex < group.counters.size() && resultCount < maxResults; + ++counterIndex) + { + const PerfMonitorCounter &counter = group.counters[counterIndex]; + PerfMonitorTriplet &triplet = resultsOut[resultCount++]; + triplet.counter = static_cast(counterIndex); + triplet.group = static_cast(groupIndex); + triplet.value = counter.value; + } + } + byteCount += sizeof(PerfMonitorTriplet) * resultCount; + break; + } + default: + UNREACHABLE(); + } -void Context::getPerfMonitorCounterInfo(GLuint group, GLuint counter, GLenum pname, void *data) {} + if (bytesWritten) + { + *bytesWritten = byteCount; + } +} + +void Context::getPerfMonitorCounterInfo(GLuint group, GLuint counter, GLenum pname, void *data) +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + ASSERT(group < perfMonitorGroups.size()); + const PerfMonitorCounters &counters = perfMonitorGroups[group].counters; + ASSERT(counter < counters.size()); + + switch (pname) + { + case GL_COUNTER_TYPE_AMD: + { + GLenum *dataOut = reinterpret_cast(data); + *dataOut = GL_UNSIGNED_INT; + break; + } + case GL_COUNTER_RANGE_AMD: + { + GLuint *dataOut = reinterpret_cast(data); + dataOut[0] = 0; + dataOut[1] = std::numeric_limits::max(); + break; + } + default: + UNREACHABLE(); + } +} void Context::getPerfMonitorCounterString(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString) -{} +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + ASSERT(group < perfMonitorGroups.size()); + const PerfMonitorCounters &counters = perfMonitorGroups[group].counters; + ASSERT(counter < counters.size()); + GetPerfMonitorString(counters[counter].name, bufSize, length, counterString); +} void Context::getPerfMonitorCounters(GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) -{} +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + ASSERT(group < perfMonitorGroups.size()); + const PerfMonitorCounters &groupCounters = perfMonitorGroups[group].counters; + + if (numCounters) + { + *numCounters = static_cast(groupCounters.size()); + } + + if (maxActiveCounters) + { + *maxActiveCounters = static_cast(groupCounters.size()); + } + + if (counters) + { + GLsizei maxCounterIndex = std::min(counterSize, static_cast(groupCounters.size())); + for (GLsizei counterIndex = 0; counterIndex < maxCounterIndex; ++counterIndex) + { + counters[counterIndex] = static_cast(counterIndex); + } + } +} void Context::getPerfMonitorGroupString(GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString) -{} +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + ASSERT(group < perfMonitorGroups.size()); + GetPerfMonitorString(perfMonitorGroups[group].name, bufSize, length, groupString); +} -void Context::getPerfMonitorGroups(GLint *numGroups, GLsizei groupsSize, GLuint *groups) {} +void Context::getPerfMonitorGroups(GLint *numGroups, GLsizei groupsSize, GLuint *groups) +{ + using namespace angle; + const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters(); + + if (numGroups) + { + *numGroups = static_cast(perfMonitorGroups.size()); + } + + GLuint maxGroupIndex = + std::min(groupsSize, static_cast(perfMonitorGroups.size())); + for (GLuint groupIndex = 0; groupIndex < maxGroupIndex; ++groupIndex) + { + groups[groupIndex] = groupIndex; + } +} void Context::selectPerfMonitorCounters(GLuint monitor, GLboolean enable, @@ -9425,6 +9593,11 @@ void Context::selectPerfMonitorCounters(GLuint monitor, GLuint *counterList) {} +const angle::PerfMonitorCounterGroups &Context::getPerfMonitorCounterGroups() const +{ + return mImplementation->getPerfMonitorCounters(); +} + // ErrorSet implementation. ErrorSet::ErrorSet(Context *context) : mContext(context) {} diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h index b3e0ccd39..957edc36c 100644 --- a/src/libANGLE/Context.h +++ b/src/libANGLE/Context.h @@ -649,6 +649,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl // Needed by capture serialization logic that works with a "const" Context pointer. void finishImmutable() const; + const angle::PerfMonitorCounterGroups &getPerfMonitorCounterGroups() const; + private: void initializeDefaultResources(); diff --git a/src/libANGLE/ErrorStrings.h b/src/libANGLE/ErrorStrings.h index 6f28ba895..d947fe2fb 100644 --- a/src/libANGLE/ErrorStrings.h +++ b/src/libANGLE/ErrorStrings.h @@ -312,6 +312,9 @@ MSG kInvalidName = "Invalid name."; MSG kInvalidNameCharacters = "Name contains invalid characters."; MSG kInvalidOriginEnum = "Invalid origin enum."; MSG kInvalidPackParametersForWebGL = "Invalid combination of pack parameters for WebGL."; +MSG kInvalidPerfMonitor = "Invalid perf monitor."; +MSG kInvalidPerfMonitorCounter = "Invalid perf monitor counter."; +MSG kInvalidPerfMonitorGroup = "Invalid perf monitor counter group."; MSG kInvalidPname = "Invalid pname."; MSG kInvalidPointerQuery = "Invalid pointer query."; MSG kInvalidPointParameter = "Invalid point parameter."; diff --git a/src/libANGLE/capture/capture_gles_ext_params.cpp b/src/libANGLE/capture/capture_gles_ext_params.cpp index 009a3fed7..936fcd9d7 100644 --- a/src/libANGLE/capture/capture_gles_ext_params.cpp +++ b/src/libANGLE/capture/capture_gles_ext_params.cpp @@ -4074,7 +4074,7 @@ void CaptureGetPerfMonitorCounterDataAMD_data(const State &glState, GLint *bytesWritten, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = dataSize; } void CaptureGetPerfMonitorCounterDataAMD_bytesWritten(const State &glState, @@ -4086,7 +4086,7 @@ void CaptureGetPerfMonitorCounterDataAMD_bytesWritten(const State &glState, GLint *bytesWritten, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = sizeof(GLint); } void CaptureGetPerfMonitorCounterInfoAMD_data(const State &glState, @@ -4109,7 +4109,7 @@ void CaptureGetPerfMonitorCounterStringAMD_length(const State &glState, GLchar *counterString, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = sizeof(GLsizei); } void CaptureGetPerfMonitorCounterStringAMD_counterString(const State &glState, @@ -4121,7 +4121,7 @@ void CaptureGetPerfMonitorCounterStringAMD_counterString(const State &glState, GLchar *counterString, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = bufSize; } void CaptureGetPerfMonitorCountersAMD_numCounters(const State &glState, @@ -4133,7 +4133,7 @@ void CaptureGetPerfMonitorCountersAMD_numCounters(const State &glState, GLuint *counters, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = sizeof(GLint); } void CaptureGetPerfMonitorCountersAMD_maxActiveCounters(const State &glState, @@ -4145,7 +4145,7 @@ void CaptureGetPerfMonitorCountersAMD_maxActiveCounters(const State &glState, GLuint *counters, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = sizeof(GLint); } void CaptureGetPerfMonitorCountersAMD_counters(const State &glState, @@ -4157,7 +4157,7 @@ void CaptureGetPerfMonitorCountersAMD_counters(const State &glState, GLuint *counters, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = counterSize * sizeof(GLuint); } void CaptureGetPerfMonitorGroupStringAMD_length(const State &glState, @@ -4168,7 +4168,7 @@ void CaptureGetPerfMonitorGroupStringAMD_length(const State &glState, GLchar *groupString, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = sizeof(GLsizei); } void CaptureGetPerfMonitorGroupStringAMD_groupString(const State &glState, @@ -4179,7 +4179,7 @@ void CaptureGetPerfMonitorGroupStringAMD_groupString(const State &glState, GLchar *groupString, angle::ParamCapture *paramCapture) { - UNIMPLEMENTED(); + paramCapture->readBufferSizeBytes = bufSize; } void CaptureGetPerfMonitorGroupsAMD_numGroups(const State &glState, diff --git a/src/libANGLE/renderer/ContextImpl.cpp b/src/libANGLE/renderer/ContextImpl.cpp index 41541dc32..952d4ee37 100644 --- a/src/libANGLE/renderer/ContextImpl.cpp +++ b/src/libANGLE/renderer/ContextImpl.cpp @@ -9,6 +9,7 @@ #include "libANGLE/renderer/ContextImpl.h" +#include "common/third_party/base/anglebase/no_destructor.h" #include "libANGLE/Context.h" namespace rx @@ -79,4 +80,9 @@ angle::Result ContextImpl::releaseTextures(const gl::Context *context, return angle::Result::Stop; } +const angle::PerfMonitorCounterGroups &ContextImpl::getPerfMonitorCounters() +{ + static angle::base::NoDestructor sCounters; + return *sCounters; +} } // namespace rx diff --git a/src/libANGLE/renderer/ContextImpl.h b/src/libANGLE/renderer/ContextImpl.h index 68068021d..26d8eb9cb 100644 --- a/src/libANGLE/renderer/ContextImpl.h +++ b/src/libANGLE/renderer/ContextImpl.h @@ -256,6 +256,9 @@ class ContextImpl : public GLImplFactory virtual angle::Result releaseTextures(const gl::Context *context, gl::TextureBarrierVector *textureBarriers); + // AMD_performance_monitor + virtual const angle::PerfMonitorCounterGroups &getPerfMonitorCounters(); + protected: const gl::State &mState; gl::MemoryProgramCache *mMemoryProgramCache; diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp index 742c65b65..5acf429fe 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -848,6 +848,23 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk mDescriptorBufferInfos.reserve(kDescriptorBufferInfosInitialSize); mDescriptorImageInfos.reserve(kDescriptorImageInfosInitialSize); mWriteDescriptorSets.reserve(kDescriptorWriteInfosInitialSize); + + angle::PerfMonitorCounterGroup vulkanGroup; + vulkanGroup.name = "vulkan"; + +#define ANGLE_ADD_PERF_MONITOR_COUNTER_GROUP(COUNTER) \ + { \ + angle::PerfMonitorCounter counter; \ + counter.name = #COUNTER; \ + counter.value = 0; \ + vulkanGroup.counters.push_back(counter); \ + } + + ANGLE_VK_PERF_COUNTERS_X(ANGLE_ADD_PERF_MONITOR_COUNTER_GROUP) + +#undef ANGLE_ADD_PERF_MONITOR_COUNTER_GROUP + + mPerfMonitorCounters.push_back(vulkanGroup); } ContextVk::~ContextVk() = default; @@ -6872,4 +6889,20 @@ ProgramExecutableVk *ContextVk::getExecutable() const } return nullptr; } + +const angle::PerfMonitorCounterGroups &ContextVk::getPerfMonitorCounters() +{ + syncObjectPerfCounters(); + + angle::PerfMonitorCounters &counters = + angle::GetPerfMonitorCounterGroup(mPerfMonitorCounters, "vulkan").counters; + +#define ANGLE_UPDATE_PERF_MAP(COUNTER) \ + angle::GetPerfMonitorCounter(counters, #COUNTER).value = mPerfCounters.COUNTER; + + ANGLE_VK_PERF_COUNTERS_X(ANGLE_UPDATE_PERF_MAP) + +#undef ANGLE_UPDATE_PERF_MAP + return mPerfMonitorCounters; +} } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h index 636276fa1..568da24a6 100755 --- a/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/src/libANGLE/renderer/vulkan/ContextVk.h @@ -652,8 +652,8 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; } - const vk::PerfCounters &getPerfCounters() const { return mPerfCounters; } - vk::PerfCounters &getPerfCounters() { return mPerfCounters; } + const angle::VulkanPerfCounters &getPerfCounters() const { return mPerfCounters; } + angle::VulkanPerfCounters &getPerfCounters() { return mPerfCounters; } // Implementation of MultisampleTextureInitializer angle::Result initializeMultisampleTextureToBlack(const gl::Context *context, @@ -688,6 +688,8 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText return angle::Result::Continue; } + const angle::PerfMonitorCounterGroups &getPerfMonitorCounters() override; + private: // Dirty bits. enum DirtyBitType : size_t @@ -1210,7 +1212,8 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText uint64_t mGpuEventTimestampOrigin; // A mix of per-frame and per-run counters. - vk::PerfCounters mPerfCounters; + angle::VulkanPerfCounters mPerfCounters; + angle::PerfMonitorCounterGroups mPerfMonitorCounters; ContextVkPerfCounters mContextPerfCounters; ContextVkPerfCounters mCumulativeContextPerfCounters; diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp index d0b1202b5..1d324c4d5 100644 --- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp +++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp @@ -1459,7 +1459,7 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk, resolveRegion.extent.height = params.blitArea.height; resolveRegion.extent.depth = 1; - vk::PerfCounters &perfCounters = contextVk->getPerfCounters(); + angle::VulkanPerfCounters &perfCounters = contextVk->getPerfCounters(); for (size_t colorIndexGL : mState.getEnabledDrawBuffers()) { RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[colorIndexGL]; diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp index ab5e86118..0c90e08ad 100644 --- a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp +++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp @@ -1278,7 +1278,7 @@ void GetRenderPassAndUpdateCounters(ContextVk *contextVk, *renderPassOut = &renderPassHelper->getRenderPass(); if (updatePerfCounters) { - PerfCounters &counters = contextVk->getPerfCounters(); + angle::VulkanPerfCounters &counters = contextVk->getPerfCounters(); const RenderPassPerfCounters &rpCounters = renderPassHelper->getPerfCounters(); counters.depthClears += rpCounters.depthClears; diff --git a/src/libANGLE/renderer/vulkan/vk_utils.h b/src/libANGLE/renderer/vulkan/vk_utils.h index 48dc3549c..28fac8660 100644 --- a/src/libANGLE/renderer/vulkan/vk_utils.h +++ b/src/libANGLE/renderer/vulkan/vk_utils.h @@ -1246,43 +1246,6 @@ struct RenderPassPerfCounters uint8_t readOnlyDepthStencil; }; -struct PerfCounters -{ - uint32_t primaryBuffers; - uint32_t renderPasses; - uint32_t writeDescriptorSets; - uint32_t flushedOutsideRenderPassCommandBuffers; - uint32_t resolveImageCommands; - uint32_t depthClears; - uint32_t depthLoads; - uint32_t depthStores; - uint32_t stencilClears; - uint32_t stencilLoads; - uint32_t stencilStores; - uint32_t colorAttachmentUnresolves; - uint32_t depthAttachmentUnresolves; - uint32_t stencilAttachmentUnresolves; - uint32_t colorAttachmentResolves; - uint32_t depthAttachmentResolves; - uint32_t stencilAttachmentResolves; - uint32_t readOnlyDepthStencilRenderPasses; - uint32_t descriptorSetAllocations; - uint32_t descriptorSetCacheTotalSize; - uint32_t descriptorSetCacheKeySizeBytes; - uint32_t uniformsAndXfbDescriptorSetCacheHits; - uint32_t uniformsAndXfbDescriptorSetCacheMisses; - uint32_t uniformsAndXfbDescriptorSetCacheTotalSize; - uint32_t textureDescriptorSetCacheHits; - uint32_t textureDescriptorSetCacheMisses; - uint32_t textureDescriptorSetCacheTotalSize; - uint32_t shaderBuffersDescriptorSetCacheHits; - uint32_t shaderBuffersDescriptorSetCacheMisses; - uint32_t shaderBuffersDescriptorSetCacheTotalSize; - uint32_t buffersGhosted; - uint32_t vertexArraySyncStateCalls; - uint32_t allocateNewBufferBlockCalls; -}; - // A Vulkan image level index. using LevelIndex = gl::LevelIndexWrapper; diff --git a/src/libANGLE/validationESEXT.cpp b/src/libANGLE/validationESEXT.cpp index bce00a9f8..d16953014 100644 --- a/src/libANGLE/validationESEXT.cpp +++ b/src/libANGLE/validationESEXT.cpp @@ -2697,6 +2697,7 @@ bool ValidateBeginPerfMonitorAMD(const Context *context, return false; } + UNIMPLEMENTED(); return false; } @@ -2711,6 +2712,7 @@ bool ValidateDeletePerfMonitorsAMD(const Context *context, return false; } + UNIMPLEMENTED(); return false; } @@ -2722,6 +2724,7 @@ bool ValidateEndPerfMonitorAMD(const Context *context, angle::EntryPoint entryPo return false; } + UNIMPLEMENTED(); return false; } @@ -2736,6 +2739,7 @@ bool ValidateGenPerfMonitorsAMD(const Context *context, return false; } + UNIMPLEMENTED(); return false; } @@ -2753,7 +2757,25 @@ bool ValidateGetPerfMonitorCounterDataAMD(const Context *context, return false; } - return false; + if (monitor != 0) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitor); + return false; + } + + switch (pname) + { + case GL_PERFMON_RESULT_AVAILABLE_AMD: + case GL_PERFMON_RESULT_SIZE_AMD: + case GL_PERFMON_RESULT_AMD: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + return true; } bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context, @@ -2769,7 +2791,32 @@ bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context, return false; } - return false; + const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups(); + + if (group >= groups.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup); + return false; + } + + if (counter >= groups[group].counters.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorCounter); + return false; + } + + switch (pname) + { + case GL_COUNTER_TYPE_AMD: + case GL_COUNTER_RANGE_AMD: + break; + + default: + context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); + return false; + } + + return true; } bool ValidateGetPerfMonitorCounterStringAMD(const Context *context, @@ -2786,7 +2833,21 @@ bool ValidateGetPerfMonitorCounterStringAMD(const Context *context, return false; } - return false; + const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups(); + + if (group >= groups.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup); + return false; + } + + if (counter >= groups[group].counters.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorCounter); + return false; + } + + return true; } bool ValidateGetPerfMonitorCountersAMD(const Context *context, @@ -2803,7 +2864,15 @@ bool ValidateGetPerfMonitorCountersAMD(const Context *context, return false; } - return false; + const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups(); + + if (group >= groups.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup); + return false; + } + + return true; } bool ValidateGetPerfMonitorGroupStringAMD(const Context *context, @@ -2819,7 +2888,15 @@ bool ValidateGetPerfMonitorGroupStringAMD(const Context *context, return false; } - return false; + const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups(); + + if (group >= groups.size()) + { + context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup); + return false; + } + + return true; } bool ValidateGetPerfMonitorGroupsAMD(const Context *context, @@ -2834,7 +2911,7 @@ bool ValidateGetPerfMonitorGroupsAMD(const Context *context, return false; } - return false; + return true; } bool ValidateSelectPerfMonitorCountersAMD(const Context *context, @@ -2851,6 +2928,7 @@ bool ValidateSelectPerfMonitorCountersAMD(const Context *context, return false; } + UNIMPLEMENTED(); return false; } } // namespace gl diff --git a/src/tests/angle_end2end_tests.gni b/src/tests/angle_end2end_tests.gni index c3368e6c9..55c412add 100644 --- a/src/tests/angle_end2end_tests.gni +++ b/src/tests/angle_end2end_tests.gni @@ -150,6 +150,7 @@ angle_end2end_tests_sources = [ "gl_tests/UnpackRowLength.cpp", "gl_tests/VertexAttributeTest.cpp", "gl_tests/ViewportTest.cpp", + "gl_tests/VulkanPerformanceCounterTest.cpp", "gl_tests/WEBGLVideoTextureTest.cpp", "gl_tests/WebGLCompatibilityTest.cpp", "gl_tests/WebGLCompressedTextureAvailabilityTest.cpp", diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt index 4fc9cf8f9..ce3bc12de 100644 --- a/src/tests/angle_end2end_tests_expectations.txt +++ b/src/tests/angle_end2end_tests_expectations.txt @@ -527,3 +527,5 @@ // NVidia fails new SwizzledChainedAssignIncrement test on GL and GLES. 7029 NVIDIA OPENGL : GLSLTest.SwizzledChainedAssignIncrement/* = SKIP 7029 NVIDIA GLES : GLSLTest.SwizzledChainedAssignIncrement/* = SKIP + +7085 : VulkanPerformanceCounterTest.InvalidateDrawDisable/* = SKIP diff --git a/src/tests/angle_white_box_tests.gni b/src/tests/angle_white_box_tests.gni index 69b768e43..b547713d4 100644 --- a/src/tests/angle_white_box_tests.gni +++ b/src/tests/angle_white_box_tests.gni @@ -22,6 +22,5 @@ angle_white_box_tests_vulkan_sources = [ "gl_tests/VulkanFormatTablesTest.cpp", "gl_tests/VulkanFramebufferTest.cpp", "gl_tests/VulkanMultithreadingTest.cpp", - "gl_tests/VulkanPerformanceCounterTest.cpp", "gl_tests/VulkanUniformUpdatesTest.cpp", ] diff --git a/src/tests/capture_replay_tests/capture_replay_expectations.txt b/src/tests/capture_replay_tests/capture_replay_expectations.txt index 1fd12db11..60ae9c98b 100644 --- a/src/tests/capture_replay_tests/capture_replay_expectations.txt +++ b/src/tests/capture_replay_tests/capture_replay_expectations.txt @@ -203,3 +203,5 @@ # GLES 3.2 tests that fail because of missing features 5366 : GeometryShaderTestES32.MaxGeometryImageUniforms/* = CRASH 5366 : ProgramPipelineTest32.MaxGeometryImageUniforms/* = CRASH + +7088 : VulkanPerformanceCounterTest* = SKIP_FOR_CAPTURE diff --git a/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp b/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp index aa864243c..13ab8956f 100644 --- a/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp +++ b/src/tests/gl_tests/VulkanPerformanceCounterTest.cpp @@ -16,9 +16,6 @@ // But 'None' is also defined as a numeric constant 0L in . // So we need to include ANGLETest.h first to avoid this conflict. -#include "libANGLE/Context.h" -#include "libANGLE/angletypes.h" -#include "libANGLE/renderer/vulkan/ContextVk.h" #include "test_utils/gl_raii.h" #include "util/random_utils.h" @@ -26,6 +23,57 @@ using namespace angle; namespace { +constexpr char kExtensionName[] = "GL_AMD_performance_monitor"; + +using CounterNameToIndexMap = std::map; + +CounterNameToIndexMap BuildCounterNameToIndexMap() +{ + GLint numCounters = 0; + glGetPerfMonitorCountersAMD(0, &numCounters, nullptr, 0, nullptr); + EXPECT_GL_NO_ERROR(); + + std::vector counterIndexes(numCounters, 0); + glGetPerfMonitorCountersAMD(0, nullptr, nullptr, numCounters, counterIndexes.data()); + EXPECT_GL_NO_ERROR(); + + CounterNameToIndexMap indexMap; + + for (GLuint counterIndex : counterIndexes) + { + static constexpr size_t kBufSize = 1000; + char buffer[kBufSize] = {}; + glGetPerfMonitorCounterStringAMD(0, counterIndex, kBufSize, nullptr, buffer); + EXPECT_GL_NO_ERROR(); + + indexMap[buffer] = counterIndex; + } + + return indexMap; +} + +void UpdatePerfCounter(const CounterNameToIndexMap &counterIndexMap, + GLuint *counterOut, + const char *name, + std::vector &triplets) +{ + auto iter = counterIndexMap.find(name); + ASSERT(iter != counterIndexMap.end()); + GLuint counterIndex = iter->second; + + for (const angle::PerfMonitorTriplet &triplet : triplets) + { + ASSERT(triplet.group == 0); + if (triplet.counter == counterIndex) + { + *counterOut = triplet.value; + return; + } + } + + UNREACHABLE(); +} + class VulkanPerformanceCounterTest : public ANGLETest { protected: @@ -41,16 +89,6 @@ class VulkanPerformanceCounterTest : public ANGLETest setConfigStencilBits(8); } - const rx::vk::PerfCounters &hackANGLE() const - { - // Hack the angle! - const gl::Context *context = static_cast(getEGLWindow()->getContext()); - rx::ContextVk *contextVk = rx::GetImplAs(context); - // This will be implicitly called when using the extension. - contextVk->syncObjectPerfCounters(); - return contextVk->getPerfCounters(); - } - static constexpr GLsizei kInvalidateTestSize = 16; void setupClearAndDrawForInvalidateTest(GLProgram *program, @@ -88,7 +126,7 @@ class VulkanPerformanceCounterTest : public ANGLETest ASSERT_GL_NO_ERROR(); } - void setExpectedCountersForInvalidateTest(const rx::vk::PerfCounters &counters, + void setExpectedCountersForInvalidateTest(const angle::VulkanPerfCounters &counters, uint32_t incrementalRenderPasses, uint32_t incrementalDepthClears, uint32_t incrementalDepthLoads, @@ -96,7 +134,7 @@ class VulkanPerformanceCounterTest : public ANGLETest uint32_t incrementalStencilClears, uint32_t incrementalStencilLoads, uint32_t incrementalStencilStores, - rx::vk::PerfCounters *expected) + angle::VulkanPerfCounters *expected) { expected->renderPasses = counters.renderPasses + incrementalRenderPasses; expected->depthClears = counters.depthClears + incrementalDepthClears; @@ -107,8 +145,8 @@ class VulkanPerformanceCounterTest : public ANGLETest expected->stencilStores = counters.stencilStores + incrementalStencilStores; } - void compareDepthStencilCountersForInvalidateTest(const rx::vk::PerfCounters &counters, - const rx::vk::PerfCounters &expected) + void compareDepthStencilCountersForInvalidateTest(const angle::VulkanPerfCounters &counters, + const angle::VulkanPerfCounters &expected) { EXPECT_EQ(expected.depthClears, counters.depthClears); EXPECT_EQ(expected.depthLoads, counters.depthLoads); @@ -118,30 +156,30 @@ class VulkanPerformanceCounterTest : public ANGLETest EXPECT_EQ(expected.stencilStores, counters.stencilStores); } - void setAndIncrementLoadCountersForInvalidateTest(const rx::vk::PerfCounters &counters, + void setAndIncrementLoadCountersForInvalidateTest(const angle::VulkanPerfCounters &counters, uint32_t incrementalDepthLoads, uint32_t incrementalStencilLoads, - rx::vk::PerfCounters *expected) + angle::VulkanPerfCounters *expected) { expected->depthLoads = counters.depthLoads + incrementalDepthLoads; expected->stencilLoads = counters.stencilLoads + incrementalStencilLoads; } - void compareLoadCountersForInvalidateTest(const rx::vk::PerfCounters &counters, - const rx::vk::PerfCounters &expected) + void compareLoadCountersForInvalidateTest(const angle::VulkanPerfCounters &counters, + const angle::VulkanPerfCounters &expected) { EXPECT_EQ(expected.depthLoads, counters.depthLoads); EXPECT_EQ(expected.stencilLoads, counters.stencilLoads); } - void setExpectedCountersForUnresolveResolveTest(const rx::vk::PerfCounters &counters, + void setExpectedCountersForUnresolveResolveTest(const angle::VulkanPerfCounters &counters, uint32_t incrementalColorAttachmentUnresolves, uint32_t incrementalDepthAttachmentUnresolves, uint32_t incrementalStencilAttachmentUnresolves, uint32_t incrementalColorAttachmentResolves, uint32_t incrementalDepthAttachmentResolves, uint32_t incrementalStencilAttachmentResolves, - rx::vk::PerfCounters *expected) + angle::VulkanPerfCounters *expected) { expected->colorAttachmentUnresolves = counters.colorAttachmentUnresolves + incrementalColorAttachmentUnresolves; @@ -157,8 +195,8 @@ class VulkanPerformanceCounterTest : public ANGLETest counters.stencilAttachmentResolves + incrementalStencilAttachmentResolves; } - void compareCountersForUnresolveResolveTest(const rx::vk::PerfCounters &counters, - const rx::vk::PerfCounters &expected) + void compareCountersForUnresolveResolveTest(const angle::VulkanPerfCounters &counters, + const angle::VulkanPerfCounters &expected) { EXPECT_EQ(expected.colorAttachmentUnresolves, counters.colorAttachmentUnresolves); EXPECT_EQ(expected.depthAttachmentUnresolves, counters.depthAttachmentUnresolves); @@ -172,6 +210,39 @@ class VulkanPerformanceCounterTest : public ANGLETest EXPECT_EQ(expected.depthAttachmentResolves, counters.depthAttachmentResolves); EXPECT_EQ(expected.stencilAttachmentResolves, counters.stencilAttachmentResolves); } + + angle::VulkanPerfCounters getPerfCounters() + { + GLuint resultSize = 0; + glGetPerfMonitorCounterDataAMD(0, GL_PERFMON_RESULT_SIZE_AMD, sizeof(GLuint), &resultSize, + nullptr); + EXPECT_GL_NO_ERROR(); + EXPECT_GT(resultSize, 0u); + + std::vector perfResults(resultSize / + sizeof(angle::PerfMonitorTriplet)); + glGetPerfMonitorCounterDataAMD(0, GL_PERFMON_RESULT_AMD, + perfResults.size() * sizeof(perfResults[0]), + &perfResults.data()->group, nullptr); + + if (mIndexMap.empty()) + { + mIndexMap = BuildCounterNameToIndexMap(); + } + + angle::VulkanPerfCounters counters; + +#define ANGLE_UNPACK_PERF_COUNTER(COUNTER) \ + UpdatePerfCounter(mIndexMap, &counters.COUNTER, #COUNTER, perfResults); + + ANGLE_VK_PERF_COUNTERS_X(ANGLE_UNPACK_PERF_COUNTER) + +#undef ANGLE_UNPACK_PERF_COUNTER + + return counters; + } + + CounterNameToIndexMap mIndexMap; }; class VulkanPerformanceCounterTest_ES31 : public VulkanPerformanceCounterTest @@ -190,7 +261,7 @@ class VulkanPerformanceCounterTest_MSAA : public VulkanPerformanceCounterTest // Tests that texture updates to unused textures don't break the RP. TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); GLColor kInitialData[4] = {GLColor::red, GLColor::blue, GLColor::green, GLColor::yellow}; @@ -220,7 +291,8 @@ TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass) glDrawArrays(GL_TRIANGLES, 0, 6); ASSERT_GL_NO_ERROR(); - uint32_t expectedRenderPassCount = counters.renderPasses; + + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses; // Step 2: Introduce a new 2D Texture with the same Program and Framebuffer. GLTexture newTexture; @@ -232,14 +304,14 @@ TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass) glDrawArrays(GL_TRIANGLES, 0, 6); ASSERT_GL_NO_ERROR(); - uint32_t actualRenderPassCount = counters.renderPasses; + uint32_t actualRenderPassCount = getPerfCounters().renderPasses; EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount); } // Tests that RGB texture should not break renderpass. TEST_P(VulkanPerformanceCounterTest, SampleFromRGBTextureDoesNotBreakRenderPass) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D()); glUseProgram(program); @@ -262,7 +334,7 @@ TEST_P(VulkanPerformanceCounterTest, SampleFromRGBTextureDoesNotBreakRenderPass) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; // First draw with textureRGBA which should start the renderpass glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -275,14 +347,14 @@ TEST_P(VulkanPerformanceCounterTest, SampleFromRGBTextureDoesNotBreakRenderPass) drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); - uint32_t actualRenderPassCount = counters.renderPasses; + uint32_t actualRenderPassCount = getPerfCounters().renderPasses; EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount); } // Tests that RGB texture should not break renderpass. -TEST_P(VulkanPerformanceCounterTest, renderToRGBTextureDoesNotBreakRenderPass) +TEST_P(VulkanPerformanceCounterTest, RenderToRGBTextureDoesNotBreakRenderPass) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor()); glUseProgram(program); @@ -304,7 +376,7 @@ TEST_P(VulkanPerformanceCounterTest, renderToRGBTextureDoesNotBreakRenderPass) ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_NO_ERROR(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; // Draw into FBO glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); @@ -314,14 +386,14 @@ TEST_P(VulkanPerformanceCounterTest, renderToRGBTextureDoesNotBreakRenderPass) glUniform4fv(colorUniformLocation, 1, GLColor::blue.toNormalizedVector().data()); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); - uint32_t actualRenderPassCount = counters.renderPasses; + uint32_t actualRenderPassCount = getPerfCounters().renderPasses; EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount); } // Tests that changing a Texture's max level hits the descriptor set cache. TEST_P(VulkanPerformanceCounterTest, ChangingMaxLevelHitsDescriptorCache) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); GLColor kInitialData[4] = {GLColor::red, GLColor::blue, GLColor::green, GLColor::yellow}; @@ -359,20 +431,22 @@ TEST_P(VulkanPerformanceCounterTest, ChangingMaxLevelHitsDescriptorCache) glDrawArrays(GL_TRIANGLES, 0, 6); ASSERT_GL_NO_ERROR(); - uint32_t expectedWriteDescriptorSetCount = counters.writeDescriptorSets; + uint32_t expectedWriteDescriptorSetCount = getPerfCounters().writeDescriptorSets; // Step 3: Change max level back to original value and verify we hit the cache. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); glDrawArrays(GL_TRIANGLES, 0, 6); ASSERT_GL_NO_ERROR(); - uint32_t actualWriteDescriptorSetCount = counters.writeDescriptorSets; + uint32_t actualWriteDescriptorSetCount = getPerfCounters().writeDescriptorSets; EXPECT_EQ(expectedWriteDescriptorSetCount, actualWriteDescriptorSetCount); } // Tests that two glCopyBufferSubData commands can share a barrier. TEST_P(VulkanPerformanceCounterTest, IndependentBufferCopiesShareSingleBarrier) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + constexpr GLint srcDataA[] = {1, 2, 3, 4}; constexpr GLint srcDataB[] = {5, 6, 7, 8}; @@ -394,8 +468,7 @@ TEST_P(VulkanPerformanceCounterTest, IndependentBufferCopiesShareSingleBarrier) glBufferData(GL_COPY_WRITE_BUFFER, sizeof(srcDataB[0]) * 2, nullptr, GL_STATIC_COPY); // We expect that ANGLE generate zero additional command buffers. - const rx::vk::PerfCounters &counters = hackANGLE(); - uint32_t expectedFlushCount = counters.flushedOutsideRenderPassCommandBuffers; + uint32_t expectedFlushCount = getPerfCounters().flushedOutsideRenderPassCommandBuffers; // Step 2: Do the two copies. glBindBuffer(GL_COPY_READ_BUFFER, srcA); @@ -410,7 +483,7 @@ TEST_P(VulkanPerformanceCounterTest, IndependentBufferCopiesShareSingleBarrier) ASSERT_GL_NO_ERROR(); - uint32_t actualFlushCount = counters.flushedOutsideRenderPassCommandBuffers; + uint32_t actualFlushCount = getPerfCounters().flushedOutsideRenderPassCommandBuffers; EXPECT_EQ(expectedFlushCount, actualFlushCount); } @@ -418,6 +491,8 @@ TEST_P(VulkanPerformanceCounterTest, IndependentBufferCopiesShareSingleBarrier) // used TEST_P(VulkanPerformanceCounterTest_ES31, MultisampleResolveWithBlit) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + constexpr int kSize = 16; glViewport(0, 0, kSize, kSize); @@ -455,8 +530,7 @@ TEST_P(VulkanPerformanceCounterTest_ES31, MultisampleResolveWithBlit) glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST); ASSERT_GL_NO_ERROR(); - const rx::vk::PerfCounters &counters = hackANGLE(); - EXPECT_EQ(counters.resolveImageCommands, 0u); + EXPECT_EQ(getPerfCounters().resolveImageCommands, 0u); glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO); constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2; @@ -470,7 +544,7 @@ TEST_P(VulkanPerformanceCounterTest_ES31, MultisampleResolveWithBlit) // Ensures a read-only depth-stencil feedback loop works in a single RenderPass. TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthStencilFeedbackLoopUsesSingleRenderPass) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); constexpr GLsizei kSize = 4; @@ -512,7 +586,7 @@ TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthStencilFeedbackLoopUsesSingleR glDrawArrays(GL_TRIANGLES, 0, 6); ASSERT_GL_NO_ERROR(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; // Start new RenderPass with depth write disabled and no loop. glBindFramebuffer(GL_FRAMEBUFFER, depthAndColorFBO); @@ -545,7 +619,7 @@ TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthStencilFeedbackLoopUsesSingleR glDrawArrays(GL_TRIANGLES, 0, 6); ASSERT_GL_NO_ERROR(); - uint32_t actualRenderPassCount = counters.renderPasses; + uint32_t actualRenderPassCount = getPerfCounters().renderPasses; EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount); // Do a final write to depth to make sure we can switch out of read-only mode. @@ -560,11 +634,12 @@ TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthStencilFeedbackLoopUsesSingleR // - Scenario: invalidate, disable, draw TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDraw) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -588,18 +663,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDraw) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 0, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that alternative PUBG MOBILE case does not break render pass, and that counts are correct: @@ -607,11 +682,12 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDraw) // - Scenario: disable, invalidate, draw TEST_P(VulkanPerformanceCounterTest, DisableInvalidateDraw) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -635,18 +711,18 @@ TEST_P(VulkanPerformanceCounterTest, DisableInvalidateDraw) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 0, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another case does not break render pass, and that counts are correct: @@ -654,11 +730,12 @@ TEST_P(VulkanPerformanceCounterTest, DisableInvalidateDraw) // - Scenario: disable, draw, invalidate, enable TEST_P(VulkanPerformanceCounterTest, DisableDrawInvalidateEnable) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -690,21 +767,21 @@ TEST_P(VulkanPerformanceCounterTest, DisableDrawInvalidateEnable) // dirty bit to be processed // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Break the render pass by reading back a pixel. EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 0, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that common TRex case does not break render pass, and that counts are correct: @@ -712,11 +789,12 @@ TEST_P(VulkanPerformanceCounterTest, DisableDrawInvalidateEnable) // - Scenario: invalidate TEST_P(VulkanPerformanceCounterTest, Invalidate) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -732,29 +810,30 @@ TEST_P(VulkanPerformanceCounterTest, Invalidate) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 0, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Similar to Invalidate, but uses glInvalidateSubFramebuffer such that the given area covers the // whole framebuffer. TEST_P(VulkanPerformanceCounterTest, InvalidateSub) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -771,18 +850,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateSub) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 0, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another case does not break render pass, and that counts are correct: @@ -790,11 +869,12 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateSub) // - Scenario: invalidate, draw TEST_P(VulkanPerformanceCounterTest, InvalidateDraw) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -814,18 +894,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDraw) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 1, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 1, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another case does not break render pass, and that counts are correct: @@ -833,14 +913,15 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDraw) // - Scenario: invalidate, draw, disable TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisable) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + // http://anglebug.com/6857 ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan()); - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -867,18 +948,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisable) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 1, 1, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 1, 1, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another case does not break render pass, and that counts are correct: @@ -886,11 +967,11 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisable) // - Scenario: invalidate, disable, draw, enable TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDrawEnable) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -920,18 +1001,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDrawEnable) // dirty bit to be processed // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 0, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another case does not break render pass, and that counts are correct: @@ -939,11 +1020,11 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDrawEnable) // - Scenario: invalidate, disable, draw, enable, draw TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDrawEnableDraw) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -975,18 +1056,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDrawEnableDraw) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 1, 1, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 1, 1, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another case does not break render pass, and that counts are correct: @@ -994,11 +1075,11 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDisableDrawEnableDraw) // - Scenario: invalidate, draw, disable, enable TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnable) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -1031,18 +1112,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnable) // dirty bit to be processed // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 1, 1, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 1, 1, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another case does not break render pass, and that counts are correct: @@ -1050,11 +1131,11 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnable) // - Scenario: invalidate, draw, disable, enable, invalidate TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnableInvalidate) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -1089,18 +1170,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnableInvalidate) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 0, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another case does not break render pass, and that counts are correct: @@ -1108,11 +1189,11 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnableInvalidate) // - Scenario: invalidate, draw, disable, enable, invalidate, draw TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnableInvalidateDraw) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -1151,18 +1232,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnableInvalidateDraw) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 1, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 1, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that another common (dEQP) case does not break render pass, and that counts are correct: @@ -1170,11 +1251,11 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawDisableEnableInvalidateDraw) // - Scenario: invalidate, disable, enable, draw TEST_P(VulkanPerformanceCounterTest, InvalidateDisableEnableDraw) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -1205,28 +1286,28 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDisableEnableDraw) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 1, 1, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 1, 1, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that an in renderpass clear after invalidate keeps content stored. TEST_P(VulkanPerformanceCounterTest, InvalidateAndClear) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -1250,10 +1331,10 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateAndClear) // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Expect rpCount+1, depth(Clears+0, Loads+1, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 0, 0, 1, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 0, 0, 1, 1, 0, 0, 0, &expected); // Bind FBO again and try to use the depth buffer without clear. This should result in // loadOp=LOAD and StoreOP=STORE @@ -1265,18 +1346,18 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateAndClear) // Should pass depth test: (0.5+1.0)/2.0=0.75 < 1.0 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f); EXPECT_PIXEL_COLOR_EQ(kInvalidateTestSize / 2, kInvalidateTestSize / 2, GLColor::blue); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that the draw path for clear after invalidate and disabling depth/stencil test keeps // content stored. TEST_P(VulkanPerformanceCounterTest, InvalidateAndMaskedClear) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+1, Load+0, Stores+1) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 1, 0, 1, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 1, 0, 1, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -1308,10 +1389,10 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateAndMaskedClear) // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Expect rpCount+1, depth(Clears+0, Loads+1, Stores+1), stencil(Clears+0, Load+1, Stores+1) - setExpectedCountersForInvalidateTest(counters, 0, 0, 1, 1, 0, 1, 1, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 0, 0, 1, 1, 0, 1, 1, &expected); // Bind FBO again and try to use the depth buffer without clear. This should result in // loadOp=LOAD and StoreOP=STORE @@ -1325,7 +1406,7 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateAndMaskedClear) ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue()); drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.95f); EXPECT_PIXEL_COLOR_EQ(kInvalidateTestSize / 2, kInvalidateTestSize / 2, GLColor::blue); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); } // Tests whether depth-stencil ContentDefined will be correct when: @@ -1333,11 +1414,11 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateAndMaskedClear) // - Scenario: invalidate, detach D/S texture and modify it, attach D/S texture, draw with blend TEST_P(VulkanPerformanceCounterTest, InvalidateDetachModifyTexAttachDrawWithBlend) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+1) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green()); @@ -1373,9 +1454,9 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDetachModifyTexAttachDrawWithBlen ASSERT_GL_NO_ERROR(); // Check for the expected number of render passes, expected color, and other expected counters - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Detach depth-stencil attachment glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); @@ -1397,24 +1478,24 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDetachModifyTexAttachDrawWithBlen // Draw again, showing that the modified depth-stencil value prevents a new color value // // Expect rpCount+1, depth(Clears+0, Loads+1, Stores+1), stencil(Clears+0, Load+1, Stores+1) - setExpectedCountersForInvalidateTest(counters, 1, 0, 1, 1, 0, 1, 1, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 0, 1, 1, 0, 1, 1, &expected); drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); // Check for the expected number of render passes, expected color, and other expected counters - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Draw again, using a different depth value, so that the drawing takes place // // Expect rpCount+1, depth(Clears+0, Loads+1, Stores+1), stencil(Clears+0, Load+1, Stores+1) - setExpectedCountersForInvalidateTest(counters, 1, 0, 1, 1, 0, 1, 1, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 0, 1, 1, 0, 1, 1, &expected); drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.2f); ASSERT_GL_NO_ERROR(); // Check for the expected number of render passes, expected color, and other expected counters - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that a GLRenderbuffer can be deleted before the render pass ends, and that everything @@ -1423,11 +1504,11 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDetachModifyTexAttachDrawWithBlen // - Scenario: invalidate TEST_P(VulkanPerformanceCounterTest, InvalidateDrawAndDeleteRenderbuffer) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+1), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 1, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 1, 0, 0, 0, &expected); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); GLFramebuffer framebuffer; @@ -1448,27 +1529,27 @@ TEST_P(VulkanPerformanceCounterTest, InvalidateDrawAndDeleteRenderbuffer) ASSERT_GL_NO_ERROR(); // Ensure that the render pass wasn't broken - EXPECT_EQ(expected.renderPasses, counters.renderPasses); + EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses); } // The renderbuffer should now be deleted. // Use swapBuffers and then check how many loads and stores were actually done swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Start and end another render pass, to check that the load ops are as expected - setAndIncrementLoadCountersForInvalidateTest(counters, 0, 0, &expected); + setAndIncrementLoadCountersForInvalidateTest(getPerfCounters(), 0, 0, &expected); drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); swapBuffers(); - compareLoadCountersForInvalidateTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that even if the app clears depth, it should be invalidated if there is no read. TEST_P(VulkanPerformanceCounterTest, SwapShouldInvalidateDepthAfterClear) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red()); @@ -1482,18 +1563,18 @@ TEST_P(VulkanPerformanceCounterTest, SwapShouldInvalidateDepthAfterClear) drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); - uint32_t expectedDepthClears = counters.depthClears; + uint32_t expectedDepthClears = getPerfCounters().depthClears; swapBuffers(); - uint32_t actualDepthClears = counters.depthClears; + uint32_t actualDepthClears = getPerfCounters().depthClears; EXPECT_EQ(expectedDepthClears, actualDepthClears); } // Tests that masked color clears don't break the RP. TEST_P(VulkanPerformanceCounterTest, MaskedColorClearDoesNotBreakRenderPass) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); GLTexture texture; glBindTexture(GL_TEXTURE_2D, texture); @@ -1505,7 +1586,7 @@ TEST_P(VulkanPerformanceCounterTest, MaskedColorClearDoesNotBreakRenderPass) ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_NO_ERROR(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; // Mask color channels and clear the framebuffer multiple times. glClearColor(0.25f, 0.25f, 0.25f, 0.25f); @@ -1524,7 +1605,7 @@ TEST_P(VulkanPerformanceCounterTest, MaskedColorClearDoesNotBreakRenderPass) glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); glClear(GL_COLOR_BUFFER_BIT); - uint32_t actualRenderPassCount = counters.renderPasses; + uint32_t actualRenderPassCount = getPerfCounters().renderPasses; EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount); EXPECT_PIXEL_NEAR(0, 0, 63, 127, 255, 191, 1); @@ -1533,7 +1614,7 @@ TEST_P(VulkanPerformanceCounterTest, MaskedColorClearDoesNotBreakRenderPass) // Tests that masked color/depth/stencil clears don't break the RP. TEST_P(VulkanPerformanceCounterTest, MaskedClearDoesNotBreakRenderPass) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); constexpr GLsizei kSize = 64; @@ -1553,7 +1634,7 @@ TEST_P(VulkanPerformanceCounterTest, MaskedClearDoesNotBreakRenderPass) ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_NO_ERROR(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); @@ -1582,7 +1663,7 @@ TEST_P(VulkanPerformanceCounterTest, MaskedClearDoesNotBreakRenderPass) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Make sure the render pass wasn't broken. - EXPECT_EQ(expectedRenderPassCount, counters.renderPasses); + EXPECT_EQ(expectedRenderPassCount, getPerfCounters().renderPasses); // Verify that clear was done correctly. EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow); @@ -1614,11 +1695,11 @@ TEST_P(VulkanPerformanceCounterTest, MaskedClearDoesNotBreakRenderPass) // Tests that clear followed by scissored draw uses loadOp to clear. TEST_P(VulkanPerformanceCounterTest, ClearThenScissoredDraw) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; - uint32_t expectedDepthClears = counters.depthClears + 1; - uint32_t expectedStencilClears = counters.stencilClears + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; + uint32_t expectedDepthClears = getPerfCounters().depthClears + 1; + uint32_t expectedStencilClears = getPerfCounters().stencilClears + 1; constexpr GLsizei kSize = 64; @@ -1668,9 +1749,9 @@ TEST_P(VulkanPerformanceCounterTest, ClearThenScissoredDraw) ASSERT_GL_NO_ERROR(); // Make sure a single render pass was used and depth/stencil clear used loadOp=CLEAR. - EXPECT_EQ(expectedRenderPassCount, counters.renderPasses); - EXPECT_EQ(expectedDepthClears, counters.depthClears); - EXPECT_EQ(expectedStencilClears, counters.stencilClears); + EXPECT_EQ(expectedRenderPassCount, getPerfCounters().renderPasses); + EXPECT_EQ(expectedDepthClears, getPerfCounters().depthClears); + EXPECT_EQ(expectedStencilClears, getPerfCounters().stencilClears); // Verify correctness. EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); @@ -1687,7 +1768,7 @@ TEST_P(VulkanPerformanceCounterTest, ClearThenScissoredDraw) // Tests that scissored clears don't break the RP. TEST_P(VulkanPerformanceCounterTest, ScissoredClearDoesNotBreakRenderPass) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); constexpr GLsizei kSize = 64; @@ -1707,7 +1788,7 @@ TEST_P(VulkanPerformanceCounterTest, ScissoredClearDoesNotBreakRenderPass) ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_NO_ERROR(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); @@ -1736,7 +1817,7 @@ TEST_P(VulkanPerformanceCounterTest, ScissoredClearDoesNotBreakRenderPass) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Make sure the render pass wasn't broken. - EXPECT_EQ(expectedRenderPassCount, counters.renderPasses); + EXPECT_EQ(expectedRenderPassCount, getPerfCounters().renderPasses); // Verify that clear was done correctly. EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); @@ -1785,7 +1866,7 @@ TEST_P(VulkanPerformanceCounterTest, ScissoredClearDoesNotBreakRenderPass) // Tests that draw buffer change with all color channel mask off should not break renderpass TEST_P(VulkanPerformanceCounterTest, DrawbufferChangeWithAllColorMaskDisabled) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor()); glUseProgram(program); @@ -1814,7 +1895,7 @@ TEST_P(VulkanPerformanceCounterTest, DrawbufferChangeWithAllColorMaskDisabled) ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER); ASSERT_GL_NO_ERROR(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; // Draw into FBO glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); @@ -1837,15 +1918,15 @@ TEST_P(VulkanPerformanceCounterTest, DrawbufferChangeWithAllColorMaskDisabled) glUniform4fv(colorUniformLocation, 1, GLColor::red.toNormalizedVector().data()); drawQuad(program, essl1_shaders::PositionAttrib(), 0.7f); - uint32_t actualRenderPassCount = counters.renderPasses; + uint32_t actualRenderPassCount = getPerfCounters().renderPasses; EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount); } // Tests the optimization that a glFlush call issued inside a renderpass will be skipped. TEST_P(VulkanPerformanceCounterTest, InRenderpassFlushShouldNotBreakRenderpass) { - const rx::vk::PerfCounters &counters = hackANGLE(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; GLTexture texture; glBindTexture(GL_TEXTURE_2D, texture); @@ -1864,21 +1945,22 @@ TEST_P(VulkanPerformanceCounterTest, InRenderpassFlushShouldNotBreakRenderpass) drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f); ASSERT_GL_NO_ERROR(); - uint32_t actualRenderPassCount = counters.renderPasses; + uint32_t actualRenderPassCount = getPerfCounters().renderPasses; EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount); } // Tests that depth/stencil texture clear/load works correctly. TEST_P(VulkanPerformanceCounterTest, DepthStencilTextureClearAndLoad) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + // TODO: http://anglebug.com/5329 Flaky test ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan()); - const rx::vk::PerfCounters &counters = hackANGLE(); - uint32_t expectedDepthClearCount = counters.depthClears + 1; - uint32_t expectedDepthLoadCount = counters.depthLoads + 3; - uint32_t expectedStencilClearCount = counters.stencilClears + 1; - uint32_t expectedStencilLoadCount = counters.stencilLoads + 3; + uint32_t expectedDepthClearCount = getPerfCounters().depthClears + 1; + uint32_t expectedDepthLoadCount = getPerfCounters().depthLoads + 3; + uint32_t expectedStencilClearCount = getPerfCounters().stencilClears + 1; + uint32_t expectedStencilLoadCount = getPerfCounters().stencilLoads + 3; constexpr GLsizei kSize = 6; @@ -1964,10 +2046,10 @@ TEST_P(VulkanPerformanceCounterTest, DepthStencilTextureClearAndLoad) ASSERT_GL_NO_ERROR(); // Verify the counters - EXPECT_EQ(counters.depthClears, expectedDepthClearCount); - EXPECT_EQ(counters.depthLoads, expectedDepthLoadCount); - EXPECT_EQ(counters.stencilClears, expectedStencilClearCount); - EXPECT_EQ(counters.stencilLoads, expectedStencilLoadCount); + EXPECT_EQ(getPerfCounters().depthClears, expectedDepthClearCount); + EXPECT_EQ(getPerfCounters().depthLoads, expectedDepthLoadCount); + EXPECT_EQ(getPerfCounters().stencilClears, expectedStencilClearCount); + EXPECT_EQ(getPerfCounters().stencilLoads, expectedStencilLoadCount); // Verify that copies were done correctly. GLFramebuffer verifyFBO; @@ -1983,16 +2065,17 @@ TEST_P(VulkanPerformanceCounterTest, DepthStencilTextureClearAndLoad) // Tests that multisampled-render-to-texture depth/stencil textures don't ever load data. TEST_P(VulkanPerformanceCounterTest, RenderToTextureDepthStencilTextureShouldNotLoad) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + // http://anglebug.com/5083 ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan()); ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2")); - const rx::vk::PerfCounters &counters = hackANGLE(); - uint32_t expectedDepthClearCount = counters.depthClears + 1; - uint32_t expectedDepthLoadCount = counters.depthLoads; - uint32_t expectedStencilClearCount = counters.stencilClears + 1; - uint32_t expectedStencilLoadCount = counters.stencilLoads; + uint32_t expectedDepthClearCount = getPerfCounters().depthClears + 1; + uint32_t expectedDepthLoadCount = getPerfCounters().depthLoads; + uint32_t expectedStencilClearCount = getPerfCounters().stencilClears + 1; + uint32_t expectedStencilLoadCount = getPerfCounters().stencilLoads; constexpr GLsizei kSize = 6; @@ -2079,10 +2162,10 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureDepthStencilTextureShouldNot ASSERT_GL_NO_ERROR(); // Verify the counters - EXPECT_EQ(counters.depthClears, expectedDepthClearCount); - EXPECT_EQ(counters.depthLoads, expectedDepthLoadCount); - EXPECT_EQ(counters.stencilClears, expectedStencilClearCount); - EXPECT_EQ(counters.stencilLoads, expectedStencilLoadCount); + EXPECT_EQ(getPerfCounters().depthClears, expectedDepthClearCount); + EXPECT_EQ(getPerfCounters().depthLoads, expectedDepthLoadCount); + EXPECT_EQ(getPerfCounters().stencilClears, expectedStencilClearCount); + EXPECT_EQ(getPerfCounters().stencilLoads, expectedStencilLoadCount); // Verify that copies were done correctly. Only the first copy can be verified because the // contents of the depth/stencil buffer is undefined after the first render pass break, meaning @@ -2110,9 +2193,9 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureDepthStencilRenderbufferShou ANGLE_SKIP_TEST_IF(IsWindows7() && IsNVIDIA() && IsVulkan()); ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture")); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + angle::VulkanPerfCounters expected; // This test creates 4 render passes. In the first render pass, color, depth and stencil are // cleared. In the following render passes, they must be loaded. However, given that the @@ -2121,10 +2204,10 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureDepthStencilRenderbufferShou // Expect rpCount+4, depth(Clears+1, Loads+3, Stores+3), stencil(Clears+1, Load+3, Stores+3). // Note that the Loads and Stores are from the resolve attachments. - setExpectedCountersForInvalidateTest(counters, 4, 1, 3, 3, 1, 3, 3, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 4, 1, 3, 3, 1, 3, 3, &expected); // Additionally, expect 4 resolves and 3 unresolves. - setExpectedCountersForUnresolveResolveTest(counters, 3, 3, 3, 4, 4, 4, &expected); + setExpectedCountersForUnresolveResolveTest(getPerfCounters(), 3, 3, 3, 4, 4, 4, &expected); constexpr GLsizei kSize = 6; @@ -2210,8 +2293,8 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureDepthStencilRenderbufferShou ASSERT_GL_NO_ERROR(); // Verify the counters - compareLoadCountersForInvalidateTest(counters, expected); - compareCountersForUnresolveResolveTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); + compareCountersForUnresolveResolveTest(getPerfCounters(), expected); // Verify that copies were done correctly. GLFramebuffer verifyFBO; @@ -2233,8 +2316,9 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureInvalidate) ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture")); - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + + angle::VulkanPerfCounters expected; // This test creates 4 render passes. In the first render pass, color, depth and stencil are // cleared. After every render pass, the attachments are invalidated. In the following render @@ -2243,10 +2327,10 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureInvalidate) // should resolve the attachments. // Expect rpCount+4, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+1, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 4, 1, 0, 0, 1, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 4, 1, 0, 0, 1, 0, 0, &expected); // Additionally, expect no resolve and unresolve. - setExpectedCountersForUnresolveResolveTest(counters, 0, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForUnresolveResolveTest(getPerfCounters(), 0, 0, 0, 0, 0, 0, &expected); constexpr GLsizei kSize = 6; @@ -2345,8 +2429,8 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureInvalidate) ASSERT_GL_NO_ERROR(); // Verify the counters - compareLoadCountersForInvalidateTest(counters, expected); - compareCountersForUnresolveResolveTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); + compareCountersForUnresolveResolveTest(getPerfCounters(), expected); } // Tests counters when uninitialized multisampled-render-to-texture depth/stencil renderbuffers are @@ -2358,14 +2442,14 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureUninitializedAndUnusedDepthS ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture")); - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, no depth/stencil clear, load or store. - setExpectedCountersForInvalidateTest(counters, 1, 0, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 0, 0, 0, 0, 0, 0, &expected); // Additionally, expect only color resolve. - setExpectedCountersForUnresolveResolveTest(counters, 0, 0, 0, 1, 0, 0, &expected); + setExpectedCountersForUnresolveResolveTest(getPerfCounters(), 0, 0, 0, 1, 0, 0, &expected); constexpr GLsizei kSize = 6; @@ -2417,20 +2501,20 @@ TEST_P(VulkanPerformanceCounterTest, RenderToTextureUninitializedAndUnusedDepthS ASSERT_GL_NO_ERROR(); // Verify the counters - compareLoadCountersForInvalidateTest(counters, expected); - compareCountersForUnresolveResolveTest(counters, expected); + compareLoadCountersForInvalidateTest(getPerfCounters(), expected); + compareCountersForUnresolveResolveTest(getPerfCounters(), expected); } // Ensures we use read-only depth layout when there is no write TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthBufferLayout) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); constexpr GLsizei kSize = 64; // Create depth only FBO and fill depth texture to leftHalf=0.0 and rightHalf=1.0. This should // use writeable layout - uint32_t expectedReadOnlyDepthStencilCount = counters.readOnlyDepthStencilRenderPasses; + uint32_t expectedReadOnlyDepthStencilCount = getPerfCounters().readOnlyDepthStencilRenderPasses; GLTexture depthTexture; glBindTexture(GL_TEXTURE_2D, depthTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, kSize, kSize, 0, GL_DEPTH_COMPONENT, @@ -2458,11 +2542,11 @@ TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthBufferLayout) // here to end the renderpass. glFinish(); - uint32_t actualReadOnlyDepthStencilCount = counters.readOnlyDepthStencilRenderPasses; + uint32_t actualReadOnlyDepthStencilCount = getPerfCounters().readOnlyDepthStencilRenderPasses; EXPECT_EQ(expectedReadOnlyDepthStencilCount, actualReadOnlyDepthStencilCount); // Create a color+depth FBO and use depth as read only. This should use read only layout - expectedReadOnlyDepthStencilCount = counters.readOnlyDepthStencilRenderPasses + 1; + expectedReadOnlyDepthStencilCount = getPerfCounters().readOnlyDepthStencilRenderPasses + 1; GLTexture colorTexture; glBindTexture(GL_TEXTURE_2D, colorTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); @@ -2476,7 +2560,8 @@ TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthBufferLayout) glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glDepthMask(GL_FALSE); - GLfloat *clearColor = GLColor::blue.toNormalizedVector().data(); + + angle::Vector4 clearColor = GLColor::blue.toNormalizedVector(); glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); glClear(GL_COLOR_BUFFER_BIT); drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f); @@ -2484,7 +2569,7 @@ TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthBufferLayout) // The pixel check will end renderpass. EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(1 + kSize / 2, 1, GLColor::red); - actualReadOnlyDepthStencilCount = counters.readOnlyDepthStencilRenderPasses; + actualReadOnlyDepthStencilCount = getPerfCounters().readOnlyDepthStencilRenderPasses; EXPECT_EQ(expectedReadOnlyDepthStencilCount, actualReadOnlyDepthStencilCount); } @@ -2492,11 +2577,11 @@ TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthBufferLayout) // invalidate) TEST_P(VulkanPerformanceCounterTest, RenderPassAfterRenderPassWithoutDepthStencilWrite) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+0, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 0, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 0, 0, 0, 0, 0, 0, &expected); constexpr GLsizei kSize = 64; @@ -2531,10 +2616,10 @@ TEST_P(VulkanPerformanceCounterTest, RenderPassAfterRenderPassWithoutDepthStenci // Break the render pass and ensure no depth/stencil load/store was done. swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); // Expect rpCount+1, depth(Clears+0, Loads+0, Stores+0), stencil(Clears+0, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 0, 0, 0, 0, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 0, 0, 0, 0, 0, 0, &expected); // Draw again with similar conditions, and again make sure no load/store is done. glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f); @@ -2542,7 +2627,7 @@ TEST_P(VulkanPerformanceCounterTest, RenderPassAfterRenderPassWithoutDepthStenci // Break the render pass and ensure no depth/stencil load/store was done. swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); } @@ -2551,8 +2636,8 @@ TEST_P(VulkanPerformanceCounterTest, RenderPassAfterRenderPassWithoutDepthStenci // etc) don't break the render pass. TEST_P(VulkanPerformanceCounterTest, ClearAfterClearDoesNotBreakRenderPass) { - const rx::vk::PerfCounters &counters = hackANGLE(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; constexpr GLsizei kSize = 6; @@ -2615,7 +2700,7 @@ TEST_P(VulkanPerformanceCounterTest, ClearAfterClearDoesNotBreakRenderPass) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Verify render pass count. - EXPECT_EQ(counters.renderPasses, expectedRenderPassCount); + EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount); // Make sure the result is correct. The border of the image should be blue with depth 0.3f and // stencil 0x44. The center is red with depth 1.0f and stencil 0x55. @@ -2695,6 +2780,8 @@ TEST_P(VulkanPerformanceCounterTest, ClearAfterClearDoesNotBreakRenderPass) // Ensures that changing the scissor size doesn't break the render pass. TEST_P(VulkanPerformanceCounterTest, ScissorDoesNotBreakRenderPass) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + constexpr GLsizei kSize = 16; // Create a framebuffer with a color attachment. @@ -2713,8 +2800,7 @@ TEST_P(VulkanPerformanceCounterTest, ScissorDoesNotBreakRenderPass) glClear(GL_COLOR_BUFFER_BIT); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); - const rx::vk::PerfCounters &counters = hackANGLE(); - uint32_t expectedRenderPassCount = counters.renderPasses + 1; + uint32_t expectedRenderPassCount = getPerfCounters().renderPasses + 1; // This test starts with a small scissor and gradually grows it and issues draw calls and // various kinds of clears: @@ -2838,7 +2924,7 @@ TEST_P(VulkanPerformanceCounterTest, ScissorDoesNotBreakRenderPass) ASSERT_GL_NO_ERROR(); // Verify render pass count. - EXPECT_EQ(counters.renderPasses, expectedRenderPassCount); + EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount); // Make sure the result is correct: // @@ -2940,6 +3026,8 @@ TEST_P(VulkanPerformanceCounterTest, ScissorDoesNotBreakRenderPass) // Tests that changing UBO bindings does not allocate new descriptor sets. TEST_P(VulkanPerformanceCounterTest, ChangingUBOsHitsDescriptorSetCache) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + // Set up two UBOs, one filled with "1" and the second with "2". constexpr GLsizei kCount = 64; std::vector data1(kCount, 1); @@ -3037,7 +3125,7 @@ void main() // Capture the allocations counter after the first run. if (iteration == 0) { - descriptorSetAllocationsBefore = hackANGLE().descriptorSetAllocations; + descriptorSetAllocationsBefore = getPerfCounters().descriptorSetAllocations; } } @@ -3059,7 +3147,7 @@ void main() EXPECT_EQ(expectedData, actualData); // Check for unnecessary descriptor set allocations. - uint32_t descriptorSetAllocationsAfter = hackANGLE().descriptorSetAllocations; + uint32_t descriptorSetAllocationsAfter = getPerfCounters().descriptorSetAllocations; EXPECT_EQ(descriptorSetAllocationsAfter, 0u); } @@ -3067,7 +3155,7 @@ void main() // waiting for the GPU access to complete before returning a pointer to the buffer. TEST_P(VulkanPerformanceCounterTest, MappingGpuReadOnlyBufferGhostsBuffer) { - const rx::vk::PerfCounters &counters = hackANGLE(); + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); // 1. Create a buffer, map it, fill it with red // 2. Draw with buffer (GPU read-only) @@ -3129,8 +3217,8 @@ void main() void *mappedBuffer = glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), GL_MAP_WRITE_BIT); // 'renderPasses == 0' here means the render pass was broken and a new one was started. - ASSERT_EQ(counters.renderPasses, 1u); - ASSERT_EQ(counters.buffersGhosted, 1u); + ASSERT_EQ(getPerfCounters().renderPasses, 1u); + ASSERT_EQ(getPerfCounters().buffersGhosted, 1u); memcpy(mappedBuffer, kUpdateData1.data(), sizeof(kInitialData)); @@ -3143,12 +3231,12 @@ void main() drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5); ASSERT_GL_NO_ERROR(); - ASSERT_EQ(counters.renderPasses, 1u); + ASSERT_EQ(getPerfCounters().renderPasses, 1u); // Update the buffer with glBufferSubData glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kUpdateData2), kUpdateData2.data()); ASSERT_GL_NO_ERROR(); - ASSERT_EQ(counters.renderPasses, 1u); + ASSERT_EQ(getPerfCounters().renderPasses, 1u); // Verify that the buffer has the updated value. glUniform1ui(expectLoc, kUpdateData2[0].asUint()); @@ -3156,7 +3244,7 @@ void main() drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5); ASSERT_GL_NO_ERROR(); - ASSERT_EQ(counters.renderPasses, 1u); + ASSERT_EQ(getPerfCounters().renderPasses, 1u); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan); } @@ -3164,6 +3252,8 @@ void main() // Verifies that BufferSubData calls don't trigger state updates for non-translated formats. TEST_P(VulkanPerformanceCounterTest, BufferSubDataShouldNotTriggerSyncState) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green()); glUseProgram(testProgram); @@ -3178,7 +3268,7 @@ TEST_P(VulkanPerformanceCounterTest, BufferSubDataShouldNotTriggerSyncState) ASSERT_GL_NO_ERROR(); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); - EXPECT_EQ(hackANGLE().vertexArraySyncStateCalls, 1u); + EXPECT_EQ(getPerfCounters().vertexArraySyncStateCalls, 1u); const std::array &quadVertices = GetQuadVertices(); size_t bufferSize = sizeof(quadVertices[0]) * quadVertices.size(); @@ -3189,7 +3279,7 @@ TEST_P(VulkanPerformanceCounterTest, BufferSubDataShouldNotTriggerSyncState) ASSERT_GL_NO_ERROR(); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); - EXPECT_EQ(hackANGLE().vertexArraySyncStateCalls, 1u); + EXPECT_EQ(getPerfCounters().vertexArraySyncStateCalls, 1u); // Verify the BufferData with a whole buffer size is treated like the SubData call. glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices[0]) * quadVertices.size(), @@ -3198,17 +3288,17 @@ TEST_P(VulkanPerformanceCounterTest, BufferSubDataShouldNotTriggerSyncState) ASSERT_GL_NO_ERROR(); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); - EXPECT_EQ(hackANGLE().vertexArraySyncStateCalls, 1u); + EXPECT_EQ(getPerfCounters().vertexArraySyncStateCalls, 1u); } // Verifies that rendering to backbuffer discards depth/stencil. TEST_P(VulkanPerformanceCounterTest, SwapShouldInvalidateDepthStencil) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+1, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 1, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 1, 0, 0, &expected); // Clear to verify that _some_ counters did change (as opposed to for example all being reset on // swap) @@ -3227,17 +3317,17 @@ TEST_P(VulkanPerformanceCounterTest, SwapShouldInvalidateDepthStencil) // Swap buffers to implicitely resolve swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); } // Verifies that rendering to MSAA backbuffer discards depth/stencil. TEST_P(VulkanPerformanceCounterTest_MSAA, SwapShouldInvalidateDepthStencil) { - const rx::vk::PerfCounters &counters = hackANGLE(); - rx::vk::PerfCounters expected; + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + angle::VulkanPerfCounters expected; // Expect rpCount+1, depth(Clears+1, Loads+0, Stores+0), stencil(Clears+1, Load+0, Stores+0) - setExpectedCountersForInvalidateTest(counters, 1, 1, 0, 0, 1, 0, 0, &expected); + setExpectedCountersForInvalidateTest(getPerfCounters(), 1, 1, 0, 0, 1, 0, 0, &expected); // Clear to verify that _some_ counters did change (as opposed to for example all being reset on // swap) @@ -3256,12 +3346,14 @@ TEST_P(VulkanPerformanceCounterTest_MSAA, SwapShouldInvalidateDepthStencil) // Swap buffers to implicitely resolve swapBuffers(); - compareDepthStencilCountersForInvalidateTest(counters, expected); + compareDepthStencilCountersForInvalidateTest(getPerfCounters(), expected); } // Tests that uniform updates eventually stop updating descriptor sets. TEST_P(VulkanPerformanceCounterTest, UniformUpdatesHitDescriptorSetCache) { + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kExtensionName)); + ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor()); glUseProgram(testProgram); GLint posLoc = glGetAttribLocation(testProgram, essl1_shaders::PositionAttrib()); @@ -3298,7 +3390,7 @@ TEST_P(VulkanPerformanceCounterTest, UniformUpdatesHitDescriptorSetCache) ASSERT_GL_NO_ERROR(); - uint32_t expectedCacheMisses = hackANGLE().uniformsAndXfbDescriptorSetCacheMisses; + uint32_t expectedCacheMisses = getPerfCounters().uniformsAndXfbDescriptorSetCacheMisses; EXPECT_GT(expectedCacheMisses, 0u); // Second pass: ensure all the uniforms are cached. @@ -3315,12 +3407,12 @@ TEST_P(VulkanPerformanceCounterTest, UniformUpdatesHitDescriptorSetCache) ASSERT_GL_NO_ERROR(); - uint32_t actualCacheMisses = hackANGLE().uniformsAndXfbDescriptorSetCacheMisses; + uint32_t actualCacheMisses = getPerfCounters().uniformsAndXfbDescriptorSetCacheMisses; EXPECT_EQ(expectedCacheMisses, actualCacheMisses); } -ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest, ES3_VULKAN()); -ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_ES31, ES31_VULKAN()); -ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_MSAA, ES3_VULKAN()); +ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest, ES3_VULKAN(), ES3_VULKAN_SWIFTSHADER()); +ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_ES31, ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER()); +ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_MSAA, ES3_VULKAN(), ES3_VULKAN_SWIFTSHADER()); } // anonymous namespace