Skip to content

Commit 4df556a

Browse files
vinsentlimeta-codesync[bot]
authored andcommitted
igl | add DeviceFeatures::DynamicVertexBufferStride (#427)
Summary: Pull Request resolved: #427 Reviewed By: rudybear Differential Revision: D115179384 Pulled By: corporateshark fbshipit-source-id: 67f4cd2fdfec82939c5b28f4f48ed7b10d01976f
1 parent 4591ee3 commit 4df556a

9 files changed

Lines changed: 65 additions & 146 deletions

src/igl/DeviceFeatures.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace igl {
3434
* DrawInstanced Supports IRenderCommandEncoder::draw:instanceCount
3535
* DynamicCullMode Supports setting cull mode dynamically at draw time
3636
* DynamicFrontFacingWinding Supports setting front face winding dynamically at draw time
37+
* DynamicVertexBufferStride Supports setting per-vertex-buffer attribute stride dynamically at draw time
3738
* ExplicitBinding, Supports uniforms block explicit binding in shaders
3839
* ExplicitBindingExt, Supports uniforms block explicit binding in shaders via an extension
3940
* ExternalMemoryObjects, Supports accessing external memory objects, including by POSIX file descriptor
@@ -90,6 +91,7 @@ enum class DeviceFeatures {
9091
DrawInstanced,
9192
DynamicCullMode,
9293
DynamicFrontFacingWinding,
94+
DynamicVertexBufferStride,
9395
ExplicitBinding,
9496
ExplicitBindingExt,
9597
ExternalMemoryObjects,

src/igl/metal/DeviceFeatureSet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class DeviceFeatureSet final {
4747
size_t maxBufferLength_;
4848
bool supports32BitFloatFiltering_ = false;
4949
bool supportsTimestampQueries_ = false;
50+
bool supportsDynamicVertexBufferStride_ = false;
5051
};
5152

5253
} // namespace igl::metal

src/igl/metal/DeviceFeatureSet.mm

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ size_t getGPUFamily(id<MTLDevice> device) {
144144
}
145145
}
146146
}
147+
if (@available(macOS 14.0, iOS 17.0, *)) {
148+
supportsDynamicVertexBufferStride_ = (gpuFamily_ >= 4);
149+
}
147150
}
148151

149152
/**
@@ -266,6 +269,8 @@ size_t getGPUFamily(id<MTLDevice> device) {
266269
case DeviceFeatures::DynamicCullMode:
267270
case DeviceFeatures::DynamicFrontFacingWinding:
268271
return true;
272+
case DeviceFeatures::DynamicVertexBufferStride:
273+
return supportsDynamicVertexBufferStride_;
269274
default:
270275
IGL_DEBUG_ABORT("unhandled DeviceFeatures value");
271276
break;

src/igl/opengl/DeviceFeatureSet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ bool DeviceFeatureSet::isFeatureSupportedMiscGroup(DeviceFeatures feature) const
590590

591591
case DeviceFeatures::DynamicCullMode:
592592
case DeviceFeatures::DynamicFrontFacingWinding:
593+
case DeviceFeatures::DynamicVertexBufferStride:
593594
return true;
594595

595596
default:

src/igl/tests/DeviceFeatureEnumsTest.cpp

Lines changed: 0 additions & 105 deletions
This file was deleted.

src/igl/tests/DeviceFeaturesTest.cpp

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -211,47 +211,48 @@ TEST(DeviceFeaturesEnumTest, EnumValues) {
211211
EXPECT_EQ(static_cast<int>(DeviceFeatures::DrawInstanced), 11);
212212
EXPECT_EQ(static_cast<int>(DeviceFeatures::DynamicCullMode), 12);
213213
EXPECT_EQ(static_cast<int>(DeviceFeatures::DynamicFrontFacingWinding), 13);
214-
EXPECT_EQ(static_cast<int>(DeviceFeatures::ExplicitBinding), 14);
215-
EXPECT_EQ(static_cast<int>(DeviceFeatures::ExplicitBindingExt), 15);
216-
EXPECT_EQ(static_cast<int>(DeviceFeatures::ExternalMemoryObjects), 16);
217-
EXPECT_EQ(static_cast<int>(DeviceFeatures::Indices8Bit), 17);
218-
EXPECT_EQ(static_cast<int>(DeviceFeatures::MapBufferRange), 18);
219-
EXPECT_EQ(static_cast<int>(DeviceFeatures::MeshShaders), 19);
220-
EXPECT_EQ(static_cast<int>(DeviceFeatures::MinMaxBlend), 20);
221-
EXPECT_EQ(static_cast<int>(DeviceFeatures::MultipleRenderTargets), 21);
222-
EXPECT_EQ(static_cast<int>(DeviceFeatures::MultiSample), 22);
223-
EXPECT_EQ(static_cast<int>(DeviceFeatures::MultiSampleResolve), 23);
224-
EXPECT_EQ(static_cast<int>(DeviceFeatures::Multiview), 24);
225-
EXPECT_EQ(static_cast<int>(DeviceFeatures::MultiViewMultisample), 25);
226-
EXPECT_EQ(static_cast<int>(DeviceFeatures::PushConstants), 26);
227-
EXPECT_EQ(static_cast<int>(DeviceFeatures::ReadWriteFramebuffer), 27);
228-
EXPECT_EQ(static_cast<int>(DeviceFeatures::SamplerMinMaxLod), 28);
229-
EXPECT_EQ(static_cast<int>(DeviceFeatures::ShaderLibrary), 29);
230-
EXPECT_EQ(static_cast<int>(DeviceFeatures::ShaderTextureLod), 30);
231-
EXPECT_EQ(static_cast<int>(DeviceFeatures::ShaderTextureLodExt), 31);
232-
EXPECT_EQ(static_cast<int>(DeviceFeatures::SRGB), 32);
233-
EXPECT_EQ(static_cast<int>(DeviceFeatures::SRGBSwapchain), 33);
234-
EXPECT_EQ(static_cast<int>(DeviceFeatures::SRGBWriteControl), 34);
235-
EXPECT_EQ(static_cast<int>(DeviceFeatures::StandardDerivative), 35);
236-
EXPECT_EQ(static_cast<int>(DeviceFeatures::StandardDerivativeExt), 36);
237-
EXPECT_EQ(static_cast<int>(DeviceFeatures::StorageBuffers), 37);
238-
EXPECT_EQ(static_cast<int>(DeviceFeatures::Texture2DArray), 38);
239-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureArrayExt), 39);
240-
EXPECT_EQ(static_cast<int>(DeviceFeatures::Texture3D), 40);
241-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureBindless), 41);
242-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureExternalImage), 42);
243-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureFilterAnisotropic), 43);
244-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureFloat), 44);
245-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureFormatRG), 45);
246-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureFormatRGB), 46);
247-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureHalfFloat), 47);
248-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureNotPot), 48);
249-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TexturePartialMipChain), 49);
250-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureViews), 50);
251-
EXPECT_EQ(static_cast<int>(DeviceFeatures::TimestampQueries), 51);
252-
EXPECT_EQ(static_cast<int>(DeviceFeatures::Timers), 52);
253-
EXPECT_EQ(static_cast<int>(DeviceFeatures::UniformBlocks), 53);
254-
EXPECT_EQ(static_cast<int>(DeviceFeatures::ValidationLayersEnabled), 54);
214+
EXPECT_EQ(static_cast<int>(DeviceFeatures::DynamicVertexBufferStride), 14);
215+
EXPECT_EQ(static_cast<int>(DeviceFeatures::ExplicitBinding), 15);
216+
EXPECT_EQ(static_cast<int>(DeviceFeatures::ExplicitBindingExt), 16);
217+
EXPECT_EQ(static_cast<int>(DeviceFeatures::ExternalMemoryObjects), 17);
218+
EXPECT_EQ(static_cast<int>(DeviceFeatures::Indices8Bit), 18);
219+
EXPECT_EQ(static_cast<int>(DeviceFeatures::MapBufferRange), 19);
220+
EXPECT_EQ(static_cast<int>(DeviceFeatures::MeshShaders), 20);
221+
EXPECT_EQ(static_cast<int>(DeviceFeatures::MinMaxBlend), 21);
222+
EXPECT_EQ(static_cast<int>(DeviceFeatures::MultipleRenderTargets), 22);
223+
EXPECT_EQ(static_cast<int>(DeviceFeatures::MultiSample), 23);
224+
EXPECT_EQ(static_cast<int>(DeviceFeatures::MultiSampleResolve), 24);
225+
EXPECT_EQ(static_cast<int>(DeviceFeatures::Multiview), 25);
226+
EXPECT_EQ(static_cast<int>(DeviceFeatures::MultiViewMultisample), 26);
227+
EXPECT_EQ(static_cast<int>(DeviceFeatures::PushConstants), 27);
228+
EXPECT_EQ(static_cast<int>(DeviceFeatures::ReadWriteFramebuffer), 28);
229+
EXPECT_EQ(static_cast<int>(DeviceFeatures::SamplerMinMaxLod), 29);
230+
EXPECT_EQ(static_cast<int>(DeviceFeatures::ShaderLibrary), 30);
231+
EXPECT_EQ(static_cast<int>(DeviceFeatures::ShaderTextureLod), 31);
232+
EXPECT_EQ(static_cast<int>(DeviceFeatures::ShaderTextureLodExt), 32);
233+
EXPECT_EQ(static_cast<int>(DeviceFeatures::SRGB), 33);
234+
EXPECT_EQ(static_cast<int>(DeviceFeatures::SRGBSwapchain), 34);
235+
EXPECT_EQ(static_cast<int>(DeviceFeatures::SRGBWriteControl), 35);
236+
EXPECT_EQ(static_cast<int>(DeviceFeatures::StandardDerivative), 36);
237+
EXPECT_EQ(static_cast<int>(DeviceFeatures::StandardDerivativeExt), 37);
238+
EXPECT_EQ(static_cast<int>(DeviceFeatures::StorageBuffers), 38);
239+
EXPECT_EQ(static_cast<int>(DeviceFeatures::Texture2DArray), 39);
240+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureArrayExt), 40);
241+
EXPECT_EQ(static_cast<int>(DeviceFeatures::Texture3D), 41);
242+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureBindless), 42);
243+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureExternalImage), 43);
244+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureFilterAnisotropic), 44);
245+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureFloat), 45);
246+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureFormatRG), 46);
247+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureFormatRGB), 47);
248+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureHalfFloat), 48);
249+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureNotPot), 49);
250+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TexturePartialMipChain), 50);
251+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TextureViews), 51);
252+
EXPECT_EQ(static_cast<int>(DeviceFeatures::TimestampQueries), 52);
253+
EXPECT_EQ(static_cast<int>(DeviceFeatures::Timers), 53);
254+
EXPECT_EQ(static_cast<int>(DeviceFeatures::UniformBlocks), 54);
255+
EXPECT_EQ(static_cast<int>(DeviceFeatures::ValidationLayersEnabled), 55);
255256
}
256257

257258
// ---------------------------------------------------------------------------

src/igl/tests/ogl/DeviceFeatureSetFull.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ TEST_F(DeviceFeatureSetFullOGLTest, HasFeature) {
6161
bool drawInstanced = features.hasFeature(DeviceFeatures::DrawInstanced);
6262
bool bindUniform = features.hasFeature(DeviceFeatures::BindUniform);
6363
bool mrt = features.hasFeature(DeviceFeatures::MultipleRenderTargets);
64+
bool dynamicVertexBufferStride = features.hasFeature(DeviceFeatures::DynamicVertexBufferStride);
6465

6566
// Suppress unused variable warnings
6667
(void)compute;
@@ -73,6 +74,7 @@ TEST_F(DeviceFeatureSetFullOGLTest, HasFeature) {
7374
(void)drawInstanced;
7475
(void)bindUniform;
7576
(void)mrt;
77+
(void)dynamicVertexBufferStride;
7678

7779
// The test passes if no crash occurred
7880
SUCCEED();

src/igl/tests/vulkan/DeviceExtendedVulkanTest.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,15 @@ TEST_F(DeviceExtendedVulkanTest, HasFeatureExplicitBinding) {
141141
EXPECT_TRUE(iglDev_->hasFeature(DeviceFeatures::ExplicitBinding));
142142
}
143143

144+
TEST_F(DeviceExtendedVulkanTest, HasFeatureDynamicVertexBufferStride) {
145+
// DynamicVertexBufferStride is gated on both vkCmdBindVertexBuffers2 availability and the
146+
// enableDynamicVertexBufferStride config flag (disabled by default), so the device may report
147+
// either value. Verify only that the query executes without crashing.
148+
const bool hasDynamicVertexBufferStride =
149+
iglDev_->hasFeature(DeviceFeatures::DynamicVertexBufferStride);
150+
(void)hasDynamicVertexBufferStride;
151+
}
152+
144153
TEST_F(DeviceExtendedVulkanTest, TextureFormatCapabilitiesRGBA) {
145154
const ICapabilities::TextureFormatCapabilities caps =
146155
iglDev_->getTextureFormatCapabilities(TextureFormat::RGBA_UNorm8);

src/igl/vulkan/Device.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,9 @@ bool Device::hasFeatureInternal(DeviceFeatures feature) const {
798798
return ctx_->vf_.vkCmdSetCullMode != nullptr;
799799
case DeviceFeatures::DynamicFrontFacingWinding:
800800
return ctx_->vf_.vkCmdSetFrontFace != nullptr;
801+
case DeviceFeatures::DynamicVertexBufferStride:
802+
return ctx_->vf_.vkCmdBindVertexBuffers2 != nullptr &&
803+
ctx_->config_.enableDynamicVertexBufferStride;
801804
case DeviceFeatures::Indices8Bit:
802805
return ctx_->features_.has_VK_EXT_index_type_uint8;
803806
case DeviceFeatures::ValidationLayersEnabled:

0 commit comments

Comments
 (0)