Fix bug where dynamic shader buffers are overflowing.

Change MVKPhysicalDeviceMetalFeatures::dynamicMTLBuffers from boolean to uint
dynamicMTLBufferSize limit and guard dynamic buffer usage sizes against it.
Update VK_MVK_MOLTENVK_SPEC_VERSION to 23.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index bfcf06b..fa02809 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -28,6 +28,8 @@
 - Fix `MTLHeap` memory leak in `MVKDeviceMemory`.
 - Fix tessellation break when control stage declares but does not use position builtin.
 - Fix inconsistency in reporting device local memory between type and heap on macOS.
+- Fix bug where dynamic shader buffers are overflowing.
+- Update `VK_MVK_MOLTENVK_SPEC_VERSION` to `23`.
 - Cube demo use `VK_EXT_metal_surface` extension.
 - Support *Xcode 11.3*.
 
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index 2d53d2e..45bdfa8 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -55,7 +55,7 @@
 #define MVK_MAKE_VERSION(major, minor, patch)    (((major) * 10000) + ((minor) * 100) + (patch))
 #define MVK_VERSION     MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)
 
-#define VK_MVK_MOLTENVK_SPEC_VERSION            22
+#define VK_MVK_MOLTENVK_SPEC_VERSION            23
 #define VK_MVK_MOLTENVK_EXTENSION_NAME          "VK_MVK_moltenvk"
 
 /**
@@ -528,7 +528,7 @@
     uint32_t mslVersion;                        /**< The version of the Metal Shading Language available on this device. The format of the integer is MMmmpp, with two decimal digts each for Major, minor, and patch version values (eg. MSL 1.2 would appear as 010200). */
 	VkBool32 indirectDrawing;                   /**< If true, draw calls support parameters held in a GPU buffer. */
 	VkBool32 baseVertexInstanceDrawing;         /**< If true, draw calls support specifiying the base vertex and instance. */
-    VkBool32 dynamicMTLBuffers;                 /**< If true, dynamic MTLBuffers for setting vertex, fragment, and compute bytes are supported. */
+    uint32_t dynamicMTLBufferSize;              /**< If greater than zero, dynamic MTLBuffers for setting vertex, fragment, and compute bytes are supported, and their content must be below this value. */
     VkBool32 shaderSpecialization;              /**< If true, shader specialization (aka Metal function constants) is supported. */
     VkBool32 ioSurfaces;                        /**< If true, VkImages can be underlaid by IOSurfaces via the vkUseIOSurfaceMVK() function, to support inter-process image transfers. */
     VkBool32 texelBuffers;                      /**< If true, texel buffers are supported, allowing the contents of a buffer to be interpreted as an image via a VkBufferView. */
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
index c8fbbdd..5b74c1d 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
@@ -502,7 +502,7 @@
                                        const void* bytes,
                                        NSUInteger length,
                                        uint32_t mtlBuffIndex) {
-    if (_pDeviceMetalFeatures->dynamicMTLBuffers) {
+    if (_pDeviceMetalFeatures->dynamicMTLBufferSize && length <= _pDeviceMetalFeatures->dynamicMTLBufferSize) {
         [mtlEncoder setVertexBytes: bytes length: length atIndex: mtlBuffIndex];
     } else {
         const MVKMTLBufferAllocation* mtlBuffAlloc = copyToTempMTLBufferAllocation(bytes, length);
@@ -514,7 +514,7 @@
                                          const void* bytes,
                                          NSUInteger length,
                                          uint32_t mtlBuffIndex) {
-    if (_pDeviceMetalFeatures->dynamicMTLBuffers) {
+    if (_pDeviceMetalFeatures->dynamicMTLBufferSize && length <= _pDeviceMetalFeatures->dynamicMTLBufferSize) {
         [mtlEncoder setFragmentBytes: bytes length: length atIndex: mtlBuffIndex];
     } else {
         const MVKMTLBufferAllocation* mtlBuffAlloc = copyToTempMTLBufferAllocation(bytes, length);
@@ -526,7 +526,7 @@
                                         const void* bytes,
                                         NSUInteger length,
                                         uint32_t mtlBuffIndex) {
-    if (_pDeviceMetalFeatures->dynamicMTLBuffers) {
+    if (_pDeviceMetalFeatures->dynamicMTLBufferSize && length <= _pDeviceMetalFeatures->dynamicMTLBufferSize) {
         [mtlEncoder setBytes: bytes length: length atIndex: mtlBuffIndex];
     } else {
         const MVKMTLBufferAllocation* mtlBuffAlloc = copyToTempMTLBufferAllocation(bytes, length);
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index 783c99a..ab70f77 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -791,7 +791,7 @@
 
 	_metalFeatures.maxPerStageBufferCount = 31;
     _metalFeatures.maxMTLBufferSize = (256 * MEBI);
-    _metalFeatures.dynamicMTLBuffers = false;
+    _metalFeatures.dynamicMTLBufferSize = 0;
 
     _metalFeatures.maxPerStageSamplerCount = 16;
     _metalFeatures.maxQueryBufferSize = (64 * KIBI);
@@ -812,7 +812,7 @@
 
     if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily1_v2] ) {
 		_metalFeatures.mslVersionEnum = MTLLanguageVersion1_1;
-        _metalFeatures.dynamicMTLBuffers = true;
+        _metalFeatures.dynamicMTLBufferSize = (4 * KIBI);
 		_metalFeatures.maxTextureDimension = (8 * KIBI);
     }
 
@@ -881,7 +881,7 @@
 
     if ( [_mtlDevice supportsFeatureSet: MTLFeatureSet_macOS_GPUFamily1_v2] ) {
 		_metalFeatures.mslVersionEnum = MTLLanguageVersion1_2;
-        _metalFeatures.dynamicMTLBuffers = true;
+        _metalFeatures.dynamicMTLBufferSize = (4 * KIBI);
         _metalFeatures.shaderSpecialization = true;
         _metalFeatures.stencilViews = true;
         _metalFeatures.samplerClampToBorder = true;