Don't create query pools for unsupported query types

This commit is contained in:
riperiperi 2022-05-20 22:27:48 +01:00
parent 5a6a70e3d5
commit 9f0feb8879
3 changed files with 52 additions and 14 deletions

View file

@ -6,6 +6,8 @@ namespace Ryujinx.Graphics.Vulkan
{ {
public bool SupportsConditionalRendering { get; } public bool SupportsConditionalRendering { get; }
public bool SupportsExtendedDynamicState { get; } public bool SupportsExtendedDynamicState { get; }
public bool SupportsTransformFeedback { get; }
public bool SupportsGeometryShader { get; }
public uint MinSubgroupSize { get; } public uint MinSubgroupSize { get; }
public uint MaxSubgroupSize { get; } public uint MaxSubgroupSize { get; }
public ShaderStageFlags RequiredSubgroupSizeStages { get; } public ShaderStageFlags RequiredSubgroupSizeStages { get; }
@ -13,12 +15,16 @@ namespace Ryujinx.Graphics.Vulkan
public HardwareCapabilities( public HardwareCapabilities(
bool supportsConditionalRendering, bool supportsConditionalRendering,
bool supportsExtendedDynamicState, bool supportsExtendedDynamicState,
bool supportsTransformFeedback,
bool supportsGeometryShader,
uint minSubgroupSize, uint minSubgroupSize,
uint maxSubgroupSize, uint maxSubgroupSize,
ShaderStageFlags requiredSubgroupSizeStages) ShaderStageFlags requiredSubgroupSizeStages)
{ {
SupportsConditionalRendering = supportsConditionalRendering; SupportsConditionalRendering = supportsConditionalRendering;
SupportsExtendedDynamicState = supportsExtendedDynamicState; SupportsExtendedDynamicState = supportsExtendedDynamicState;
SupportsTransformFeedback = supportsTransformFeedback;
SupportsGeometryShader = supportsGeometryShader;
MinSubgroupSize = minSubgroupSize; MinSubgroupSize = minSubgroupSize;
MaxSubgroupSize = maxSubgroupSize; MaxSubgroupSize = maxSubgroupSize;
RequiredSubgroupSizeStages = requiredSubgroupSizeStages; RequiredSubgroupSizeStages = requiredSubgroupSizeStages;

View file

@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private readonly IntPtr _bufferMap; private readonly IntPtr _bufferMap;
private readonly CounterType _type; private readonly CounterType _type;
private bool _result32Bit; private bool _result32Bit;
private bool _isSupported;
private long _defaultValue; private long _defaultValue;
@ -35,18 +36,23 @@ namespace Ryujinx.Graphics.Vulkan.Queries
_type = type; _type = type;
_result32Bit = result32Bit; _result32Bit = result32Bit;
QueryPipelineStatisticFlags flags = type == CounterType.PrimitivesGenerated ? _isSupported = QueryTypeSupported(gd, type);
QueryPipelineStatisticFlags.QueryPipelineStatisticGeometryShaderPrimitivesBit : 0;
var queryPoolCreateInfo = new QueryPoolCreateInfo() if (_isSupported)
{ {
SType = StructureType.QueryPoolCreateInfo, QueryPipelineStatisticFlags flags = type == CounterType.PrimitivesGenerated ?
QueryCount = 1, QueryPipelineStatisticFlags.QueryPipelineStatisticGeometryShaderPrimitivesBit : 0;
QueryType = GetQueryType(type),
PipelineStatistics = flags
};
gd.Api.CreateQueryPool(device, queryPoolCreateInfo, null, out _queryPool).ThrowOnError(); var queryPoolCreateInfo = new QueryPoolCreateInfo()
{
SType = StructureType.QueryPoolCreateInfo,
QueryCount = 1,
QueryType = GetQueryType(type),
PipelineStatistics = flags
};
gd.Api.CreateQueryPool(device, queryPoolCreateInfo, null, out _queryPool).ThrowOnError();
}
var buffer = gd.BufferManager.Create(gd, sizeof(long), forConditionalRendering: true); var buffer = gd.BufferManager.Create(gd, sizeof(long), forConditionalRendering: true);
@ -56,6 +62,17 @@ namespace Ryujinx.Graphics.Vulkan.Queries
_buffer = buffer; _buffer = buffer;
} }
private bool QueryTypeSupported(VulkanGraphicsDevice gd, CounterType type)
{
return type switch
{
CounterType.SamplesPassed => true,
CounterType.TransformFeedbackPrimitivesWritten => gd.Capabilities.SupportsTransformFeedback,
CounterType.PrimitivesGenerated => gd.Capabilities.SupportsGeometryShader,
_ => false
};
}
private static QueryType GetQueryType(CounterType type) private static QueryType GetQueryType(CounterType type)
{ {
return type switch return type switch
@ -80,15 +97,21 @@ namespace Ryujinx.Graphics.Vulkan.Queries
public void Begin() public void Begin()
{ {
_pipeline.BeginQuery(this, _queryPool, !_isReset); if (_isSupported)
{
_pipeline.BeginQuery(this, _queryPool, !_isReset);
}
_isReset = false; _isReset = false;
} }
public unsafe void End(bool withResult) public unsafe void End(bool withResult)
{ {
_pipeline.EndQuery(_queryPool); if (_isSupported)
{
_pipeline.EndQuery(_queryPool);
}
if (withResult) if (withResult && _isSupported)
{ {
Marshal.WriteInt64(_bufferMap, _defaultValue); Marshal.WriteInt64(_bufferMap, _defaultValue);
_pipeline.CopyQueryResults(this); _pipeline.CopyQueryResults(this);
@ -141,7 +164,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
public void PoolReset(CommandBuffer cmd) public void PoolReset(CommandBuffer cmd)
{ {
_api.CmdResetQueryPool(cmd, _queryPool, 0, 1); if (_isSupported)
{
_api.CmdResetQueryPool(cmd, _queryPool, 0, 1);
}
_isReset = true; _isReset = true;
} }
@ -170,7 +196,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
public unsafe void Dispose() public unsafe void Dispose()
{ {
_buffer.Dispose(); _buffer.Dispose();
_api.DestroyQueryPool(_device, _queryPool, null); if (_isSupported)
{
_api.DestroyQueryPool(_device, _queryPool, null);
}
_queryPool = default; _queryPool = default;
} }
} }

View file

@ -118,6 +118,7 @@ namespace Ryujinx.Graphics.Vulkan
var queueFamilyIndex = VulkanInitialization.FindSuitableQueueFamily(api, _physicalDevice, _surface, out uint maxQueueCount); var queueFamilyIndex = VulkanInitialization.FindSuitableQueueFamily(api, _physicalDevice, _surface, out uint maxQueueCount);
var supportedExtensions = VulkanInitialization.GetSupportedExtensions(api, _physicalDevice); var supportedExtensions = VulkanInitialization.GetSupportedExtensions(api, _physicalDevice);
var supportedFeatures = api.GetPhysicalDeviceFeature(_physicalDevice);
_device = VulkanInitialization.CreateDevice(api, _physicalDevice, queueFamilyIndex, supportedExtensions, maxQueueCount); _device = VulkanInitialization.CreateDevice(api, _physicalDevice, queueFamilyIndex, supportedExtensions, maxQueueCount);
@ -184,6 +185,8 @@ namespace Ryujinx.Graphics.Vulkan
Capabilities = new HardwareCapabilities( Capabilities = new HardwareCapabilities(
supportedExtensions.Contains(ExtConditionalRendering.ExtensionName), supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName), supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
supportedExtensions.Contains(ExtTransformFeedback.ExtensionName),
supportedFeatures.GeometryShader,
propertiesSubgroupSizeControl.MinSubgroupSize, propertiesSubgroupSizeControl.MinSubgroupSize,
propertiesSubgroupSizeControl.MaxSubgroupSize, propertiesSubgroupSizeControl.MaxSubgroupSize,
propertiesSubgroupSizeControl.RequiredSubgroupSizeStages); propertiesSubgroupSizeControl.RequiredSubgroupSizeStages);