Commit b6adeb2f by Shahbaz Youssefi Committed by Angle LUCI CQ

Vulkan: Use pipeline statistics query to emulate primitives generated

The VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT query produces the same result as the GL primitives generated query. One caveat is that in combination with rasterizer discard this query may not work. This is emulated by disabling rasterizer discard when this query is active and applying an empty scissor instead. When VK_EXT_primitives_generated_query is released and supported, a similar issue with rasterizer discard persists so this change will facilitate using that extension as well. Bug: angleproject:5430 Change-Id: Id45b6f058c5cb6837e04aa64b1efde28c104e4cf Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2976181 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 09bd5578
...@@ -161,11 +161,17 @@ struct FeaturesVk : FeatureSetBase ...@@ -161,11 +161,17 @@ struct FeaturesVk : FeatureSetBase
"VkDevice supports the EGL_ANDROID_native_fence_sync extension", &members, "VkDevice supports the EGL_ANDROID_native_fence_sync extension", &members,
"http://anglebug.com/2517"}; "http://anglebug.com/2517"};
// Whether the VkDevice can support imageCubeArray feature properly. // Whether the VkDevice can support the imageCubeArray feature properly.
Feature supportsImageCubeArray = {"supportsImageCubeArray", FeatureCategory::VulkanFeatures, Feature supportsImageCubeArray = {"supportsImageCubeArray", FeatureCategory::VulkanFeatures,
"VkDevice supports the imageCubeArray feature properly", "VkDevice supports the imageCubeArray feature properly",
&members, "http://anglebug.com/3584"}; &members, "http://anglebug.com/3584"};
// Whether the VkDevice supports the pipelineStatisticsQuery feature.
Feature supportsPipelineStatisticsQuery = {
"supportsPipelineStatisticsQuery", FeatureCategory::VulkanFeatures,
"VkDevice supports the pipelineStatisticsQuery feature", &members,
"http://anglebug.com/5430"};
// Whether the VkDevice supports the VK_EXT_shader_stencil_export extension, which is used to // Whether the VkDevice supports the VK_EXT_shader_stencil_export extension, which is used to
// perform multisampled resolve of stencil buffer. A multi-step workaround is used instead if // perform multisampled resolve of stencil buffer. A multi-step workaround is used instead if
// this extension is not available. // this extension is not available.
......
...@@ -678,7 +678,16 @@ angle::Result ContextVk::initialize() ...@@ -678,7 +678,16 @@ angle::Result ContextVk::initialize()
vk::kDefaultTransformFeedbackQueryPoolSize)); vk::kDefaultTransformFeedbackQueryPoolSize));
} }
// Init gles to vulkan index type map // The primitives generated query is provided through the Vulkan pipeline statistics query if
// supported. TODO: If VK_EXT_primitives_generated_query is supported, use that instead.
// http://anglebug.com/5430
if (getFeatures().supportsPipelineStatisticsQuery.enabled)
{
ANGLE_TRY(mQueryPools[gl::QueryType::PrimitivesGenerated].init(
this, VK_QUERY_TYPE_PIPELINE_STATISTICS, vk::kDefaultPrimitivesGeneratedQueryPoolSize));
}
// Init GLES to Vulkan index type map.
initIndexTypeMap(); initIndexTypeMap();
// Init driver uniforms and get the descriptor set layouts. // Init driver uniforms and get the descriptor set layouts.
...@@ -1997,13 +2006,31 @@ angle::Result ContextVk::handleDirtyGraphicsViewport(DirtyBits::Iterator *dirtyB ...@@ -1997,13 +2006,31 @@ angle::Result ContextVk::handleDirtyGraphicsViewport(DirtyBits::Iterator *dirtyB
mRenderPassCommandBuffer->setViewport(0, 1, &mViewport); mRenderPassCommandBuffer->setViewport(0, 1, &mViewport);
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ContextVk::handleDirtyGraphicsScissor(DirtyBits::Iterator *dirtyBitsIterator, angle::Result ContextVk::handleDirtyGraphicsScissor(DirtyBits::Iterator *dirtyBitsIterator,
DirtyBits dirtyBitMask) DirtyBits dirtyBitMask)
{ {
mRenderPassCommandBuffer->setScissor(0, 1, &mScissor); handleDirtyGraphicsScissorImpl(mState.isQueryActive(gl::QueryType::PrimitivesGenerated));
return angle::Result::Continue; return angle::Result::Continue;
} }
void ContextVk::handleDirtyGraphicsScissorImpl(bool isPrimitivesGeneratedQueryActive)
{
// If primitives generated query and rasterizer discard are both active, but the Vulkan
// implementation of the query does not support rasterizer discard, use an empty scissor to
// emulate it.
if (isEmulatingRasterizerDiscardDuringPrimitivesGeneratedQuery(
isPrimitivesGeneratedQueryActive))
{
VkRect2D emptyScissor = {};
mRenderPassCommandBuffer->setScissor(0, 1, &emptyScissor);
}
else
{
mRenderPassCommandBuffer->setScissor(0, 1, &mScissor);
}
}
angle::Result ContextVk::handleDirtyComputeDescriptorSets() angle::Result ContextVk::handleDirtyComputeDescriptorSets()
{ {
return handleDirtyDescriptorSetsImpl(&mOutsideRenderPassCommands->getCommandBuffer()); return handleDirtyDescriptorSetsImpl(&mOutsideRenderPassCommands->getCommandBuffer());
...@@ -3324,6 +3351,39 @@ void ContextVk::updateRasterizationSamples(const uint32_t rasterizationSamples) ...@@ -3324,6 +3351,39 @@ void ContextVk::updateRasterizationSamples(const uint32_t rasterizationSamples)
updateSampleMaskWithRasterizationSamples(rasterizationSamples); updateSampleMaskWithRasterizationSamples(rasterizationSamples);
} }
void ContextVk::updateRasterizerDiscardEnabled(bool isPrimitivesGeneratedQueryActive)
{
// On some devices, when rasterizerDiscardEnable is enabled, the
// VK_EXT_primitives_generated_query as well as the pipeline statistics query used to emulate it
// are non-functional. For VK_EXT_primitives_generated_query there's a feature bit but not for
// pipeline statistics query. If the primitives generated query is active (and rasterizer
// discard is not supported), rasterizerDiscardEnable is set to false and the functionality
// is otherwise emulated (by using an empty scissor).
// If the primitives generated query implementation supports rasterizer discard, just set
// rasterizer discard as requested. Otherwise disable it.
bool isRasterizerDiscardEnabled = mState.isRasterizerDiscardEnabled();
bool isEmulatingRasterizerDiscard = isEmulatingRasterizerDiscardDuringPrimitivesGeneratedQuery(
isPrimitivesGeneratedQueryActive);
mGraphicsPipelineDesc->updateRasterizerDiscardEnabled(
&mGraphicsPipelineTransition, isRasterizerDiscardEnabled && !isEmulatingRasterizerDiscard);
invalidateCurrentGraphicsPipeline();
if (!isEmulatingRasterizerDiscard)
{
return;
}
// If we are emulating rasterizer discard, update the scissor if in render pass. If not in
// render pass, DIRTY_BIT_SCISSOR will be set when the render pass next starts.
if (hasStartedRenderPass())
{
handleDirtyGraphicsScissorImpl(isPrimitivesGeneratedQueryActive);
}
}
void ContextVk::invalidateProgramBindingHelper(const gl::State &glState) void ContextVk::invalidateProgramBindingHelper(const gl::State &glState)
{ {
mProgram = nullptr; mProgram = nullptr;
...@@ -3543,8 +3603,8 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -3543,8 +3603,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
glState.getRasterizerState()); glState.getRasterizerState());
break; break;
case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED: case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
mGraphicsPipelineDesc->updateRasterizerDiscardEnabled( updateRasterizerDiscardEnabled(
&mGraphicsPipelineTransition, glState.isRasterizerDiscardEnabled()); mState.isQueryActive(gl::QueryType::PrimitivesGenerated));
break; break;
case gl::State::DIRTY_BIT_LINE_WIDTH: case gl::State::DIRTY_BIT_LINE_WIDTH:
mGraphicsPipelineDesc->updateLineWidth(&mGraphicsPipelineTransition, mGraphicsPipelineDesc->updateLineWidth(&mGraphicsPipelineTransition,
...@@ -3613,6 +3673,8 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -3613,6 +3673,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
glState.getFarPlane()); glState.getFarPlane());
updateColorMasks(glState.getBlendStateExt()); updateColorMasks(glState.getBlendStateExt());
updateRasterizationSamples(mDrawFramebuffer->getSamples()); updateRasterizationSamples(mDrawFramebuffer->getSamples());
updateRasterizerDiscardEnabled(
mState.isQueryActive(gl::QueryType::PrimitivesGenerated));
mGraphicsPipelineDesc->updateFrontFace(&mGraphicsPipelineTransition, mGraphicsPipelineDesc->updateFrontFace(&mGraphicsPipelineTransition,
glState.getRasterizerState(), glState.getRasterizerState(),
...@@ -4544,9 +4606,17 @@ vk::DynamicQueryPool *ContextVk::getQueryPool(gl::QueryType queryType) ...@@ -4544,9 +4606,17 @@ vk::DynamicQueryPool *ContextVk::getQueryPool(gl::QueryType queryType)
queryType == gl::QueryType::TransformFeedbackPrimitivesWritten || queryType == gl::QueryType::TransformFeedbackPrimitivesWritten ||
queryType == gl::QueryType::Timestamp || queryType == gl::QueryType::TimeElapsed); queryType == gl::QueryType::Timestamp || queryType == gl::QueryType::TimeElapsed);
// For PrimitivesGenerated queries, use the same pool as TransformFeedbackPrimitivesWritten. // For PrimitivesGenerated queries:
// They are served with the same Vulkan query. //
if (queryType == gl::QueryType::PrimitivesGenerated) // - If VK_EXT_primitives_generated_query is supported, use that.
// TODO: http://anglebug.com/5430
// - Otherwise, if pipelineStatisticsQuery is supported, use that,
// - Otherwise, use the same pool as TransformFeedbackPrimitivesWritten and share the query as
// the Vulkan transform feedback query produces both results. This option is non-conformant
// as the primitives generated query will not be functional without transform feedback.
//
if (queryType == gl::QueryType::PrimitivesGenerated &&
!getFeatures().supportsPipelineStatisticsQuery.enabled)
{ {
queryType = gl::QueryType::TransformFeedbackPrimitivesWritten; queryType = gl::QueryType::TransformFeedbackPrimitivesWritten;
} }
...@@ -5748,6 +5818,12 @@ angle::Result ContextVk::beginRenderPassQuery(QueryVk *queryVk) ...@@ -5748,6 +5818,12 @@ angle::Result ContextVk::beginRenderPassQuery(QueryVk *queryVk)
if (mRenderPassCommandBuffer) if (mRenderPassCommandBuffer)
{ {
ANGLE_TRY(queryVk->getQueryHelper()->beginRenderPassQuery(this)); ANGLE_TRY(queryVk->getQueryHelper()->beginRenderPassQuery(this));
// Update rasterizer discard emulation with primitives generated query if necessary.
if (queryVk->getType() == gl::QueryType::PrimitivesGenerated)
{
updateRasterizerDiscardEnabled(true);
}
} }
gl::QueryType type = queryVk->getType(); gl::QueryType type = queryVk->getType();
...@@ -5766,6 +5842,12 @@ angle::Result ContextVk::endRenderPassQuery(QueryVk *queryVk) ...@@ -5766,6 +5842,12 @@ angle::Result ContextVk::endRenderPassQuery(QueryVk *queryVk)
if (mRenderPassCommandBuffer) if (mRenderPassCommandBuffer)
{ {
queryVk->getQueryHelper()->endRenderPassQuery(this); queryVk->getQueryHelper()->endRenderPassQuery(this);
// Update rasterizer discard emulation with primitives generated query if necessary.
if (queryVk->getType() == gl::QueryType::PrimitivesGenerated)
{
updateRasterizerDiscardEnabled(false);
}
} }
gl::QueryType type = queryVk->getType(); gl::QueryType type = queryVk->getType();
...@@ -5788,6 +5870,9 @@ void ContextVk::pauseRenderPassQueriesIfActive() ...@@ -5788,6 +5870,9 @@ void ContextVk::pauseRenderPassQueriesIfActive()
if (activeQuery) if (activeQuery)
{ {
activeQuery->onRenderPassEnd(this); activeQuery->onRenderPassEnd(this);
// No need to update rasterizer discard emulation with primitives generated query. The
// state will be updated when the next render pass starts.
} }
} }
} }
...@@ -5802,12 +5887,40 @@ angle::Result ContextVk::resumeRenderPassQueriesIfActive() ...@@ -5802,12 +5887,40 @@ angle::Result ContextVk::resumeRenderPassQueriesIfActive()
if (activeQuery) if (activeQuery)
{ {
ANGLE_TRY(activeQuery->onRenderPassStart(this)); ANGLE_TRY(activeQuery->onRenderPassStart(this));
// Update rasterizer discard emulation with primitives generated query if necessary.
if (activeQuery->getType() == gl::QueryType::PrimitivesGenerated)
{
updateRasterizerDiscardEnabled(true);
}
} }
} }
return angle::Result::Continue; return angle::Result::Continue;
} }
bool ContextVk::doesPrimitivesGeneratedQuerySupportRasterizerDiscard() const
{
// TODO: If primitives generated is implemented with VK_EXT_primitives_generated_query, check
// the corresponding feature bit. http://anglebug.com/5430.
// If primitives generated is emulated with pipeline statistics query, it's unknown on which
// hardware rasterizer discard is supported. Assume it's supported on none.
if (getFeatures().supportsPipelineStatisticsQuery.enabled)
{
return false;
}
return true;
}
bool ContextVk::isEmulatingRasterizerDiscardDuringPrimitivesGeneratedQuery(
bool isPrimitivesGeneratedQueryActive) const
{
return isPrimitivesGeneratedQueryActive && mState.isRasterizerDiscardEnabled() &&
!doesPrimitivesGeneratedQuerySupportRasterizerDiscard();
}
QueryVk *ContextVk::getActiveRenderPassQuery(gl::QueryType queryType) const QueryVk *ContextVk::getActiveRenderPassQuery(gl::QueryType queryType) const
{ {
return mActiveRenderPassQueries[queryType]; return mActiveRenderPassQueries[queryType];
......
...@@ -589,6 +589,9 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText ...@@ -589,6 +589,9 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
angle::Result endRenderPassQuery(QueryVk *queryVk); angle::Result endRenderPassQuery(QueryVk *queryVk);
void pauseRenderPassQueriesIfActive(); void pauseRenderPassQueriesIfActive();
angle::Result resumeRenderPassQueriesIfActive(); angle::Result resumeRenderPassQueriesIfActive();
bool doesPrimitivesGeneratedQuerySupportRasterizerDiscard() const;
bool isEmulatingRasterizerDiscardDuringPrimitivesGeneratedQuery(
bool isPrimitivesGeneratedQueryActive) const;
// Used by QueryVk to share query helpers between transform feedback queries. // Used by QueryVk to share query helpers between transform feedback queries.
QueryVk *getActiveRenderPassQuery(gl::QueryType queryType) const; QueryVk *getActiveRenderPassQuery(gl::QueryType queryType) const;
...@@ -874,6 +877,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText ...@@ -874,6 +877,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
VkPipelineBindPoint bindPoint, VkPipelineBindPoint bindPoint,
DriverUniformsDescriptorSet *driverUniforms); DriverUniformsDescriptorSet *driverUniforms);
angle::Result handleDirtyDescriptorSetsImpl(vk::CommandBuffer *commandBuffer); angle::Result handleDirtyDescriptorSetsImpl(vk::CommandBuffer *commandBuffer);
void handleDirtyGraphicsScissorImpl(bool isPrimitivesGeneratedQueryActive);
angle::Result allocateDriverUniforms(size_t driverUniformsSize, angle::Result allocateDriverUniforms(size_t driverUniformsSize,
DriverUniformsDescriptorSet *driverUniforms, DriverUniformsDescriptorSet *driverUniforms,
...@@ -951,6 +955,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText ...@@ -951,6 +955,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
void updateSampleShadingWithRasterizationSamples(const uint32_t rasterizationSamples); void updateSampleShadingWithRasterizationSamples(const uint32_t rasterizationSamples);
void updateRasterizationSamples(const uint32_t rasterizationSamples); void updateRasterizationSamples(const uint32_t rasterizationSamples);
void updateRasterizerDiscardEnabled(bool isPrimitivesGeneratedQueryActive);
SpecConstUsageBits getCurrentProgramSpecConstUsageBits() const; SpecConstUsageBits getCurrentProgramSpecConstUsageBits() const;
void updateGraphicsPipelineDescWithSpecConstUsageBits(SpecConstUsageBits usageBits); void updateGraphicsPipelineDescWithSpecConstUsageBits(SpecConstUsageBits usageBits);
......
...@@ -50,10 +50,21 @@ bool IsEmulatedTransformFeedbackQuery(ContextVk *contextVk, gl::QueryType type) ...@@ -50,10 +50,21 @@ bool IsEmulatedTransformFeedbackQuery(ContextVk *contextVk, gl::QueryType type)
contextVk->getFeatures().emulateTransformFeedback.enabled; contextVk->getFeatures().emulateTransformFeedback.enabled;
} }
bool IsPrimitivesGeneratedQueryShared(ContextVk *contextVk)
{
return !contextVk->getFeatures().supportsPipelineStatisticsQuery.enabled;
}
QueryVk *GetShareQuery(ContextVk *contextVk, gl::QueryType type) QueryVk *GetShareQuery(ContextVk *contextVk, gl::QueryType type)
{ {
QueryVk *shareQuery = nullptr; QueryVk *shareQuery = nullptr;
// If the primitives generated query has its own dedicated Vulkan query, there's no sharing.
if (!IsPrimitivesGeneratedQueryShared(contextVk))
{
return nullptr;
}
switch (type) switch (type)
{ {
case gl::QueryType::PrimitivesGenerated: case gl::QueryType::PrimitivesGenerated:
...@@ -80,7 +91,8 @@ QueryVk *GetOnRenderPassStartEndShareQuery(ContextVk *contextVk, gl::QueryType t ...@@ -80,7 +91,8 @@ QueryVk *GetOnRenderPassStartEndShareQuery(ContextVk *contextVk, gl::QueryType t
gl::QueryType::PrimitivesGenerated < gl::QueryType::TransformFeedbackPrimitivesWritten, gl::QueryType::PrimitivesGenerated < gl::QueryType::TransformFeedbackPrimitivesWritten,
"incorrect assumption about the order in which queries are started in a render pass"); "incorrect assumption about the order in which queries are started in a render pass");
if (type != gl::QueryType::TransformFeedbackPrimitivesWritten) if (type != gl::QueryType::TransformFeedbackPrimitivesWritten ||
!IsPrimitivesGeneratedQueryShared(contextVk))
{ {
return nullptr; return nullptr;
} }
...@@ -206,7 +218,7 @@ angle::Result QueryVk::accumulateStashedQueryResult(ContextVk *contextVk, vk::Qu ...@@ -206,7 +218,7 @@ angle::Result QueryVk::accumulateStashedQueryResult(ContextVk *contextVk, vk::Qu
{ {
for (vk::Shared<vk::QueryHelper> &query : mStashedQueryHelpers) for (vk::Shared<vk::QueryHelper> &query : mStashedQueryHelpers)
{ {
vk::QueryResult v(getQueryResultCount()); vk::QueryResult v(getQueryResultCount(contextVk));
ANGLE_TRY(query.get().getUint64Result(contextVk, &v)); ANGLE_TRY(query.get().getUint64Result(contextVk, &v));
*result += v; *result += v;
} }
...@@ -528,7 +540,7 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait) ...@@ -528,7 +540,7 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
// stashed queries will incur a wait that is not desired by the application. // stashed queries will incur a wait that is not desired by the application.
ASSERT(!IsRenderPassQuery(contextVk, mType) || mQueryHelper.get().hasSubmittedCommands()); ASSERT(!IsRenderPassQuery(contextVk, mType) || mQueryHelper.get().hasSubmittedCommands());
vk::QueryResult result(getQueryResultCount()); vk::QueryResult result(getQueryResultCount(contextVk));
if (wait) if (wait)
{ {
...@@ -576,10 +588,14 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait) ...@@ -576,10 +588,14 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
} }
case gl::QueryType::TransformFeedbackPrimitivesWritten: case gl::QueryType::TransformFeedbackPrimitivesWritten:
mCachedResult = mCachedResult =
result.getResult(vk::QueryResult::kTransformFeedbackPrimitivesWrittenIndex); result.getResult(IsPrimitivesGeneratedQueryShared(contextVk)
? vk::QueryResult::kTransformFeedbackPrimitivesWrittenIndex
: vk::QueryResult::kDefaultResultIndex);
break; break;
case gl::QueryType::PrimitivesGenerated: case gl::QueryType::PrimitivesGenerated:
mCachedResult = result.getResult(vk::QueryResult::kPrimitivesGeneratedIndex); mCachedResult = result.getResult(IsPrimitivesGeneratedQueryShared(contextVk)
? vk::QueryResult::kPrimitivesGeneratedIndex
: vk::QueryResult::kDefaultResultIndex);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -630,11 +646,12 @@ void QueryVk::onTransformFeedbackEnd(GLsizeiptr primitivesDrawn) ...@@ -630,11 +646,12 @@ void QueryVk::onTransformFeedbackEnd(GLsizeiptr primitivesDrawn)
mTransformFeedbackPrimitivesDrawn += primitivesDrawn; mTransformFeedbackPrimitivesDrawn += primitivesDrawn;
} }
uint32_t QueryVk::getQueryResultCount() const uint32_t QueryVk::getQueryResultCount(ContextVk *contextVk) const
{ {
switch (mType) switch (mType)
{ {
case gl::QueryType::PrimitivesGenerated: case gl::QueryType::PrimitivesGenerated:
return IsPrimitivesGeneratedQueryShared(contextVk) ? 2 : 1;
case gl::QueryType::TransformFeedbackPrimitivesWritten: case gl::QueryType::TransformFeedbackPrimitivesWritten:
return 2; return 2;
default: default:
......
...@@ -53,7 +53,7 @@ class QueryVk : public QueryImpl ...@@ -53,7 +53,7 @@ class QueryVk : public QueryImpl
bool isCurrentlyInUse(Serial lastCompletedSerial) const; bool isCurrentlyInUse(Serial lastCompletedSerial) const;
angle::Result finishRunningCommands(ContextVk *contextVk); angle::Result finishRunningCommands(ContextVk *contextVk);
void stashQueryHelper(); void stashQueryHelper();
uint32_t getQueryResultCount() const; uint32_t getQueryResultCount(ContextVk *contextVk) const;
angle::Result accumulateStashedQueryResult(ContextVk *contextVk, vk::QueryResult *result); angle::Result accumulateStashedQueryResult(ContextVk *contextVk, vk::QueryResult *result);
// Manage query allocations // Manage query allocations
......
...@@ -1647,6 +1647,9 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -1647,6 +1647,9 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
// Used to implement storage buffers and images in the fragment shader: // Used to implement storage buffers and images in the fragment shader:
enabledFeatures.features.fragmentStoresAndAtomics = enabledFeatures.features.fragmentStoresAndAtomics =
mPhysicalDeviceFeatures.fragmentStoresAndAtomics; mPhysicalDeviceFeatures.fragmentStoresAndAtomics;
// Used to emulate the primitives generated query:
enabledFeatures.features.pipelineStatisticsQuery =
getFeatures().supportsPipelineStatisticsQuery.enabled;
// Used to support geometry shaders: // Used to support geometry shaders:
enabledFeatures.features.geometryShader = mPhysicalDeviceFeatures.geometryShader; enabledFeatures.features.geometryShader = mPhysicalDeviceFeatures.geometryShader;
// Used to support EXT_gpu_shader5: // Used to support EXT_gpu_shader5:
...@@ -2433,6 +2436,11 @@ void RendererVk::initFeatures(DisplayVk *displayVk, ...@@ -2433,6 +2436,11 @@ void RendererVk::initFeatures(DisplayVk *displayVk,
mPhysicalDeviceFeatures.imageCubeArray == VK_TRUE && !isSwiftShader && mPhysicalDeviceFeatures.imageCubeArray == VK_TRUE && !isSwiftShader &&
!IsPixel2(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID)); !IsPixel2(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID));
// TODO: Only enable if VK_EXT_primitives_generated_query is not present.
// http://anglebug.com/5430
ANGLE_FEATURE_CONDITION(&mFeatures, supportsPipelineStatisticsQuery,
mPhysicalDeviceFeatures.pipelineStatisticsQuery == VK_TRUE);
ANGLE_FEATURE_CONDITION(&mFeatures, preferredLargeHeapBlockSize4MB, !isQualcomm); ANGLE_FEATURE_CONDITION(&mFeatures, preferredLargeHeapBlockSize4MB, !isQualcomm);
// Defer glFLush call causes manhattan 3.0 perf regression. Let Qualcomm driver opt out from // Defer glFLush call causes manhattan 3.0 perf regression. Let Qualcomm driver opt out from
......
...@@ -2723,6 +2723,11 @@ angle::Result DynamicQueryPool::allocateNewPool(ContextVk *contextVk) ...@@ -2723,6 +2723,11 @@ angle::Result DynamicQueryPool::allocateNewPool(ContextVk *contextVk)
queryPoolInfo.queryCount = mPoolSize; queryPoolInfo.queryCount = mPoolSize;
queryPoolInfo.pipelineStatistics = 0; queryPoolInfo.pipelineStatistics = 0;
if (mQueryType == VK_QUERY_TYPE_PIPELINE_STATISTICS)
{
queryPoolInfo.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT;
}
QueryPool queryPool; QueryPool queryPool;
ANGLE_VK_TRY(contextVk, queryPool.init(contextVk->getDevice(), queryPoolInfo)); ANGLE_VK_TRY(contextVk, queryPool.init(contextVk->getDevice(), queryPoolInfo));
......
...@@ -398,9 +398,10 @@ class DynamicallyGrowingPool : angle::NonCopyable ...@@ -398,9 +398,10 @@ class DynamicallyGrowingPool : angle::NonCopyable
// another is created. The query pools live permanently, but are recycled as indices get freed. // another is created. The query pools live permanently, but are recycled as indices get freed.
// These are arbitrary default sizes for query pools. // These are arbitrary default sizes for query pools.
constexpr uint32_t kDefaultOcclusionQueryPoolSize = 64; constexpr uint32_t kDefaultOcclusionQueryPoolSize = 64;
constexpr uint32_t kDefaultTimestampQueryPoolSize = 64; constexpr uint32_t kDefaultTimestampQueryPoolSize = 64;
constexpr uint32_t kDefaultTransformFeedbackQueryPoolSize = 128; constexpr uint32_t kDefaultTransformFeedbackQueryPoolSize = 128;
constexpr uint32_t kDefaultPrimitivesGeneratedQueryPoolSize = 128;
class QueryHelper; class QueryHelper;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment