mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-11 06:17:41 +00:00
Revert "[TEST] Force checks on subgroups"
This commit is contained in:
@@ -435,7 +435,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
|
|||||||
}
|
}
|
||||||
if ((info.uses_subgroup_vote || info.uses_subgroup_invocation_id ||
|
if ((info.uses_subgroup_vote || info.uses_subgroup_invocation_id ||
|
||||||
info.uses_subgroup_shuffles) &&
|
info.uses_subgroup_shuffles) &&
|
||||||
profile.support_vote && profile.SupportsSubgroupStage(ctx.stage)) {
|
profile.support_vote) {
|
||||||
ctx.AddCapability(spv::Capability::GroupNonUniformBallot);
|
ctx.AddCapability(spv::Capability::GroupNonUniformBallot);
|
||||||
ctx.AddCapability(spv::Capability::GroupNonUniformShuffle);
|
ctx.AddCapability(spv::Capability::GroupNonUniformShuffle);
|
||||||
if (!profile.warp_size_potentially_larger_than_guest) {
|
if (!profile.warp_size_potentially_larger_than_guest) {
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -13,14 +10,7 @@ Id SubgroupScope(EmitContext& ctx) {
|
|||||||
return ctx.Const(static_cast<u32>(spv::Scope::Subgroup));
|
return ctx.Const(static_cast<u32>(spv::Scope::Subgroup));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StageSupportsSubgroups(EmitContext& ctx) {
|
|
||||||
return ctx.profile.SupportsSubgroupStage(ctx.stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
Id GetThreadId(EmitContext& ctx) {
|
Id GetThreadId(EmitContext& ctx) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return ctx.u32_zero_value;
|
|
||||||
}
|
|
||||||
return ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id);
|
return ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,9 +68,6 @@ Id GetMaxThreadId(EmitContext& ctx, Id thread_id, Id clamp, Id segmentation_mask
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id SelectValue(EmitContext& ctx, Id in_range, Id value, Id src_thread_id) {
|
Id SelectValue(EmitContext& ctx, Id in_range, Id value, Id src_thread_id) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return ctx.OpSelect(
|
return ctx.OpSelect(
|
||||||
ctx.U32[1], in_range,
|
ctx.U32[1], in_range,
|
||||||
ctx.OpGroupNonUniformShuffle(ctx.U32[1], SubgroupScope(ctx), value, src_thread_id), value);
|
ctx.OpGroupNonUniformShuffle(ctx.U32[1], SubgroupScope(ctx), value, src_thread_id), value);
|
||||||
@@ -102,9 +89,6 @@ Id EmitLaneId(EmitContext& ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id EmitVoteAll(EmitContext& ctx, Id pred) {
|
Id EmitVoteAll(EmitContext& ctx, Id pred) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return pred;
|
|
||||||
}
|
|
||||||
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
|
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
|
||||||
return ctx.OpGroupNonUniformAll(ctx.U1, SubgroupScope(ctx), pred);
|
return ctx.OpGroupNonUniformAll(ctx.U1, SubgroupScope(ctx), pred);
|
||||||
}
|
}
|
||||||
@@ -118,9 +102,6 @@ Id EmitVoteAll(EmitContext& ctx, Id pred) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id EmitVoteAny(EmitContext& ctx, Id pred) {
|
Id EmitVoteAny(EmitContext& ctx, Id pred) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return pred;
|
|
||||||
}
|
|
||||||
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
|
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
|
||||||
return ctx.OpGroupNonUniformAny(ctx.U1, SubgroupScope(ctx), pred);
|
return ctx.OpGroupNonUniformAny(ctx.U1, SubgroupScope(ctx), pred);
|
||||||
}
|
}
|
||||||
@@ -134,9 +115,6 @@ Id EmitVoteAny(EmitContext& ctx, Id pred) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id EmitVoteEqual(EmitContext& ctx, Id pred) {
|
Id EmitVoteEqual(EmitContext& ctx, Id pred) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return ctx.true_value;
|
|
||||||
}
|
|
||||||
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
|
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
|
||||||
return ctx.OpGroupNonUniformAllEqual(ctx.U1, SubgroupScope(ctx), pred);
|
return ctx.OpGroupNonUniformAllEqual(ctx.U1, SubgroupScope(ctx), pred);
|
||||||
}
|
}
|
||||||
@@ -151,9 +129,6 @@ Id EmitVoteEqual(EmitContext& ctx, Id pred) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id EmitSubgroupBallot(EmitContext& ctx, Id pred) {
|
Id EmitSubgroupBallot(EmitContext& ctx, Id pred) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return ctx.OpSelect(ctx.U32[1], pred, ctx.Const(1u), ctx.u32_zero_value);
|
|
||||||
}
|
|
||||||
const Id ballot{ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), pred)};
|
const Id ballot{ctx.OpGroupNonUniformBallot(ctx.U32[4], SubgroupScope(ctx), pred)};
|
||||||
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
|
if (!ctx.profile.warp_size_potentially_larger_than_guest) {
|
||||||
return ctx.OpCompositeExtract(ctx.U32[1], ballot, 0U);
|
return ctx.OpCompositeExtract(ctx.U32[1], ballot, 0U);
|
||||||
@@ -162,37 +137,22 @@ Id EmitSubgroupBallot(EmitContext& ctx, Id pred) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Id EmitSubgroupEqMask(EmitContext& ctx) {
|
Id EmitSubgroupEqMask(EmitContext& ctx) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return ctx.Const(1u);
|
|
||||||
}
|
|
||||||
return LoadMask(ctx, ctx.subgroup_mask_eq);
|
return LoadMask(ctx, ctx.subgroup_mask_eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitSubgroupLtMask(EmitContext& ctx) {
|
Id EmitSubgroupLtMask(EmitContext& ctx) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return ctx.u32_zero_value;
|
|
||||||
}
|
|
||||||
return LoadMask(ctx, ctx.subgroup_mask_lt);
|
return LoadMask(ctx, ctx.subgroup_mask_lt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitSubgroupLeMask(EmitContext& ctx) {
|
Id EmitSubgroupLeMask(EmitContext& ctx) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return ctx.Const(1u);
|
|
||||||
}
|
|
||||||
return LoadMask(ctx, ctx.subgroup_mask_le);
|
return LoadMask(ctx, ctx.subgroup_mask_le);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitSubgroupGtMask(EmitContext& ctx) {
|
Id EmitSubgroupGtMask(EmitContext& ctx) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return ctx.u32_zero_value;
|
|
||||||
}
|
|
||||||
return LoadMask(ctx, ctx.subgroup_mask_gt);
|
return LoadMask(ctx, ctx.subgroup_mask_gt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitSubgroupGeMask(EmitContext& ctx) {
|
Id EmitSubgroupGeMask(EmitContext& ctx) {
|
||||||
if (!StageSupportsSubgroups(ctx)) {
|
|
||||||
return ctx.Const(1u);
|
|
||||||
}
|
|
||||||
return LoadMask(ctx, ctx.subgroup_mask_ge);
|
return LoadMask(ctx, ctx.subgroup_mask_ge);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +222,7 @@ Id EmitShuffleButterfly(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id
|
|||||||
|
|
||||||
Id EmitFSwizzleAdd(EmitContext& ctx, Id op_a, Id op_b, Id swizzle) {
|
Id EmitFSwizzleAdd(EmitContext& ctx, Id op_a, Id op_b, Id swizzle) {
|
||||||
const Id three{ctx.Const(3U)};
|
const Id three{ctx.Const(3U)};
|
||||||
Id mask{GetThreadId(ctx)};
|
Id mask{ctx.OpLoad(ctx.U32[1], ctx.subgroup_local_invocation_id)};
|
||||||
mask = ctx.OpBitwiseAnd(ctx.U32[1], mask, three);
|
mask = ctx.OpBitwiseAnd(ctx.U32[1], mask, three);
|
||||||
mask = ctx.OpShiftLeftLogical(ctx.U32[1], mask, ctx.Const(1U));
|
mask = ctx.OpShiftLeftLogical(ctx.U32[1], mask, ctx.Const(1U));
|
||||||
mask = ctx.OpShiftRightLogical(ctx.U32[1], swizzle, mask);
|
mask = ctx.OpShiftRightLogical(ctx.U32[1], swizzle, mask);
|
||||||
|
|||||||
@@ -1447,7 +1447,7 @@ void EmitContext::DefineInputs(const IR::Program& program) {
|
|||||||
if (info.uses_is_helper_invocation) {
|
if (info.uses_is_helper_invocation) {
|
||||||
is_helper_invocation = DefineInput(*this, U1, false, spv::BuiltIn::HelperInvocation);
|
is_helper_invocation = DefineInput(*this, U1, false, spv::BuiltIn::HelperInvocation);
|
||||||
}
|
}
|
||||||
if (info.uses_subgroup_mask && profile.SupportsSubgroupStage(stage)) {
|
if (info.uses_subgroup_mask) {
|
||||||
subgroup_mask_eq = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupEqMaskKHR);
|
subgroup_mask_eq = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupEqMaskKHR);
|
||||||
subgroup_mask_lt = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupLtMaskKHR);
|
subgroup_mask_lt = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupLtMaskKHR);
|
||||||
subgroup_mask_le = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupLeMaskKHR);
|
subgroup_mask_le = DefineInput(*this, U32[4], false, spv::BuiltIn::SubgroupLeMaskKHR);
|
||||||
@@ -1461,10 +1461,9 @@ void EmitContext::DefineInputs(const IR::Program& program) {
|
|||||||
Decorate(subgroup_mask_ge, spv::Decoration::Flat);
|
Decorate(subgroup_mask_ge, spv::Decoration::Flat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((info.uses_fswzadd || info.uses_subgroup_invocation_id || info.uses_subgroup_shuffles ||
|
if (info.uses_fswzadd || info.uses_subgroup_invocation_id || info.uses_subgroup_shuffles ||
|
||||||
(profile.warp_size_potentially_larger_than_guest &&
|
(profile.warp_size_potentially_larger_than_guest &&
|
||||||
(info.uses_subgroup_vote || info.uses_subgroup_mask))) &&
|
(info.uses_subgroup_vote || info.uses_subgroup_mask))) {
|
||||||
profile.SupportsSubgroupStage(stage)) {
|
|
||||||
AddCapability(spv::Capability::GroupNonUniform);
|
AddCapability(spv::Capability::GroupNonUniform);
|
||||||
subgroup_local_invocation_id =
|
subgroup_local_invocation_id =
|
||||||
DefineInput(*this, U32[1], false, spv::BuiltIn::SubgroupLocalInvocationId);
|
DefineInput(*this, U32[1], false, spv::BuiltIn::SubgroupLocalInvocationId);
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
namespace Shader {
|
namespace Shader {
|
||||||
|
|
||||||
enum class Stage : u32;
|
|
||||||
|
|
||||||
struct Profile {
|
struct Profile {
|
||||||
u32 supported_spirv{0x00010000};
|
u32 supported_spirv{0x00010000};
|
||||||
bool unified_descriptor_binding{};
|
bool unified_descriptor_binding{};
|
||||||
@@ -34,7 +32,6 @@ struct Profile {
|
|||||||
bool support_fp64_signed_zero_nan_preserve{};
|
bool support_fp64_signed_zero_nan_preserve{};
|
||||||
bool support_explicit_workgroup_layout{};
|
bool support_explicit_workgroup_layout{};
|
||||||
bool support_vote{};
|
bool support_vote{};
|
||||||
u32 supported_subgroup_stages{0x7F};
|
|
||||||
bool support_viewport_index_layer_non_geometry{};
|
bool support_viewport_index_layer_non_geometry{};
|
||||||
bool support_viewport_mask{};
|
bool support_viewport_mask{};
|
||||||
bool support_typeless_image_loads{};
|
bool support_typeless_image_loads{};
|
||||||
@@ -98,10 +95,6 @@ struct Profile {
|
|||||||
|
|
||||||
u64 min_ssbo_alignment{};
|
u64 min_ssbo_alignment{};
|
||||||
u32 max_user_clip_distances{};
|
u32 max_user_clip_distances{};
|
||||||
|
|
||||||
bool SupportsSubgroupStage(Stage stage) const {
|
|
||||||
return (supported_subgroup_stages & (1u << static_cast<u32>(stage))) != 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Shader
|
} // namespace Shader
|
||||||
|
|||||||
@@ -353,20 +353,6 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||||||
serialization_thread(1, "VkPipelineSerialization") {
|
serialization_thread(1, "VkPipelineSerialization") {
|
||||||
const auto& float_control{device.FloatControlProperties()};
|
const auto& float_control{device.FloatControlProperties()};
|
||||||
const VkDriverId driver_id{device.GetDriverID()};
|
const VkDriverId driver_id{device.GetDriverID()};
|
||||||
const VkShaderStageFlags subgroup_stages{device.GetSubgroupSupportedStages()};
|
|
||||||
const auto subgroup_stage_bit{[subgroup_stages](VkShaderStageFlags flag, Shader::Stage stage) {
|
|
||||||
return (subgroup_stages & flag) != 0 ? (1u << static_cast<u32>(stage)) : 0u;
|
|
||||||
}};
|
|
||||||
const u32 supported_subgroup_stages{
|
|
||||||
subgroup_stage_bit(VK_SHADER_STAGE_VERTEX_BIT, Shader::Stage::VertexA) |
|
|
||||||
subgroup_stage_bit(VK_SHADER_STAGE_VERTEX_BIT, Shader::Stage::VertexB) |
|
|
||||||
subgroup_stage_bit(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
|
|
||||||
Shader::Stage::TessellationControl) |
|
|
||||||
subgroup_stage_bit(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
|
|
||||||
Shader::Stage::TessellationEval) |
|
|
||||||
subgroup_stage_bit(VK_SHADER_STAGE_GEOMETRY_BIT, Shader::Stage::Geometry) |
|
|
||||||
subgroup_stage_bit(VK_SHADER_STAGE_FRAGMENT_BIT, Shader::Stage::Fragment) |
|
|
||||||
subgroup_stage_bit(VK_SHADER_STAGE_COMPUTE_BIT, Shader::Stage::Compute)};
|
|
||||||
profile = Shader::Profile{
|
profile = Shader::Profile{
|
||||||
.supported_spirv = device.SupportedSpirvVersion(),
|
.supported_spirv = device.SupportedSpirvVersion(),
|
||||||
.unified_descriptor_binding = true,
|
.unified_descriptor_binding = true,
|
||||||
@@ -396,7 +382,6 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||||||
float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE,
|
float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE,
|
||||||
.support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(),
|
.support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(),
|
||||||
.support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT),
|
.support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT),
|
||||||
.supported_subgroup_stages = supported_subgroup_stages,
|
|
||||||
.support_viewport_index_layer_non_geometry =
|
.support_viewport_index_layer_non_geometry =
|
||||||
device.IsExtShaderViewportIndexLayerSupported(),
|
device.IsExtShaderViewportIndexLayerSupported(),
|
||||||
.support_viewport_mask = device.IsNvViewportArray2Supported(),
|
.support_viewport_mask = device.IsNvViewportArray2Supported(),
|
||||||
|
|||||||
@@ -998,18 +998,11 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched
|
|||||||
compute_pass_descriptor_queue);
|
compute_pass_descriptor_queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Log which unswizzle passes are active, for debugging purposes.
|
|
||||||
LOG_INFO(Render_Vulkan, "GPU compute unswizzle passes active: 2d={}, 3d={}, pitch={}",
|
|
||||||
bl_unswizzle_2d_pass.has_value(), bl_unswizzle_3d_pass.has_value(),
|
|
||||||
pitch_unswizzle_pass.has_value());
|
|
||||||
for (size_t index_a = 0; index_a < VideoCore::Surface::MaxPixelFormat; index_a++) {
|
for (size_t index_a = 0; index_a < VideoCore::Surface::MaxPixelFormat; index_a++) {
|
||||||
const auto image_format = static_cast<PixelFormat>(index_a);
|
const auto image_format = static_cast<PixelFormat>(index_a);
|
||||||
if (IsPixelFormatASTC(image_format) && !device.IsOptimalAstcSupported()) {
|
if (IsPixelFormatASTC(image_format) && !device.IsOptimalAstcSupported()) {
|
||||||
view_formats[index_a].push_back(VK_FORMAT_A8B8G8R8_UNORM_PACK32);
|
view_formats[index_a].push_back(VK_FORMAT_A8B8G8R8_UNORM_PACK32);
|
||||||
} else if (HasImageUnswizzlePasses() && !IsPixelFormatASTC(image_format) &&
|
} else if (HasImageUnswizzlePasses() && !IsPixelFormatBCn(image_format) &&
|
||||||
!IsPixelFormatBCn(image_format) &&
|
|
||||||
VideoCore::Surface::DefaultBlockWidth(image_format) == 1 &&
|
|
||||||
VideoCore::Surface::DefaultBlockHeight(image_format) == 1 &&
|
|
||||||
VideoCore::Surface::GetFormatType(image_format) ==
|
VideoCore::Surface::GetFormatType(image_format) ==
|
||||||
VideoCore::Surface::SurfaceType::ColorTexture) {
|
VideoCore::Surface::SurfaceType::ColorTexture) {
|
||||||
const u32 bytes_per_block = VideoCore::Surface::BytesPerBlock(image_format);
|
const u32 bytes_per_block = VideoCore::Surface::BytesPerBlock(image_format);
|
||||||
|
|||||||
@@ -505,8 +505,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||||||
LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken CustomBorderColor.");
|
LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken CustomBorderColor.");
|
||||||
RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color,
|
RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color,
|
||||||
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
|
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
|
||||||
RemoveExtensionFeature(extensions.border_color_swizzle, features.border_color_swizzle,
|
|
||||||
VK_EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME);
|
|
||||||
LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken shader float controls.");
|
LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken shader float controls.");
|
||||||
RemoveExtension(extensions.shader_float_controls, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
|
RemoveExtension(extensions.shader_float_controls, VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
|
||||||
LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken shader atomic int64.");
|
LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken shader atomic int64.");
|
||||||
|
|||||||
@@ -430,11 +430,6 @@ FN_MAX_LIMIT_LIST
|
|||||||
return properties.subgroup_properties.supportedOperations & feature;
|
return properties.subgroup_properties.supportedOperations & feature;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the shader stages that support subgroup operations.
|
|
||||||
VkShaderStageFlags GetSubgroupSupportedStages() const {
|
|
||||||
return properties.subgroup_properties.supportedStages;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the maximum number of push descriptors.
|
/// Returns the maximum number of push descriptors.
|
||||||
u32 MaxPushDescriptors() const {
|
u32 MaxPushDescriptors() const {
|
||||||
return properties.push_descriptor.maxPushDescriptors;
|
return properties.push_descriptor.maxPushDescriptors;
|
||||||
|
|||||||
Reference in New Issue
Block a user