Skip to content

Commit

Permalink
Merge branch 'main' into ue4-nastys-patch-env
Browse files Browse the repository at this point in the history
  • Loading branch information
italomandara committed Oct 18, 2023
2 parents 1a1221e + 9e4ee9e commit ddb725c
Show file tree
Hide file tree
Showing 20 changed files with 124 additions and 84 deletions.
6 changes: 3 additions & 3 deletions Docs/MoltenVK_Runtime_UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -617,9 +617,9 @@ vailable when you request it, resulting in frame delays and visual stuttering.
<a name="timestamping"></a>
### Timestamping

On non-Apple Silicon devices (older Mac devices), the GPU can switch power and performance
states as required by usage. This affects the GPU timestamps retrievable through the Vulkan
API. As a result, the value of `VkPhysicalDeviceLimits::timestampPeriod` can vary over time.
On non-Apple GPUs (older Mac devices), the GPU can switch power and performance states as
required by usage. This affects the GPU timestamps retrievable through the Vulkan API.
As a result, the value of `VkPhysicalDeviceLimits::timestampPeriod` can vary over time.
Consider calling `vkGetPhysicalDeviceProperties()`, when needed, and retrieve the current
value of `VkPhysicalDeviceLimits::timestampPeriod`, to help you calibrate recent GPU
timestamps queried through the Vulkan API.
Expand Down
21 changes: 16 additions & 5 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,33 @@ Copyright (c) 2015-2023 [The Brenwill Workshop Ltd.](http://www.brenwill.com)
MoltenVK 1.2.6
--------------

Released TBD
Released 2023/10/17

- Add support for extensions:
- `VK_KHR_synchronization2`
- `VK_EXT_extended_dynamic_state` *(requires Metal 3.1 for `VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE`)*
- `VK_EXT_extended_dynamic_state2`
- Fix rare case where vertex attribute buffers are not bound to Metal
when no other bindings change between pipelines.
- Fix rare case where vertex attribute buffers are not bound to Metal when no other bindings change between pipelines.
- Ensure objects retained for life of `MTLCommandBuffer` during `vkCmdBlitImage()` & `vkQueuePresentKHR()`.
- Fix case where a `CAMetalDrawable` with invalid pixel format causes onscreen flickering.
- Fix MSL code used in `vkCmdBlitImage()` on depth-stencil formats.
- Fix deadlock when reporting debug message on `MVKInstance` destruction.
- Fix MSL code used in `vkCmdBlitImage()` on depth-stencil formats.
- Improve behavior of swapchain image presentation stalls caused by Metal regression.
- `VkPhysicalDeviceLimits::timestampPeriod` set to 1.0 on Apple GPUs, and calculated dynamically on non-Apple GPUs.
- Add `MVKConfiguration::timestampPeriodLowPassAlpha` and environment variable
`MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA`, to add a configurable lowpass filter
for varying `VkPhysicalDeviceLimits::timestampPeriod` on non-Apple GPUs.
- Add several additional performance trackers, available via logging, or the `mvk_private_api.h` API.
- Add configurable lowpass filter for `VkPhysicalDeviceLimits::timestampPeriod`.
- Deprecate `MVK_DEBUG` env var, and add `MVK_CONFIG_DEBUG` env var to replace it.
- Update `MVK_CONFIGURATION_API_VERSION` and `MVK_PRIVATE_API_VERSION` to `38`.
- Update dependency libraries to match _Vulkan SDK 1.3.268_.
- Update to latest SPIRV-Cross:
- MSL: Workaround Metal 3.1 regression bug on recursive input structs.
- MSL: fix extraction of global variables, in case of atomics.
- MSL: Workaround bizarre crash on macOS.
- MSL: runtime array over argument buffers.
- MSL: Make rw texture fences optional.
- MSL: Prevent RAW hazards on read_write textures.



Expand Down
2 changes: 1 addition & 1 deletion ExternalRevisions/SPIRV-Cross_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
bccaa94db814af33d8ef05c153e7c34d8bd4d685
2de1265fca722929785d9acdec4ab728c47a0254
2 changes: 1 addition & 1 deletion ExternalRevisions/Vulkan-Headers_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
85c2334e92e215cce34e8e0ed8b2dce4700f4a50
7b3466a1f47a9251ac1113efbe022ff016e2f95b
2 changes: 1 addition & 1 deletion ExternalRevisions/Vulkan-Tools_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
300d9bf6b3cf7b237ee5e2c1d0ae10b9236f82d3
1532001f7edae559af1988293eec90bc5e2607d5
2 changes: 1 addition & 1 deletion ExternalRevisions/glslang_repo_revision
Original file line number Diff line number Diff line change
@@ -1 +1 @@
76b52ebf77833908dc4c0dd6c70a9c357ac720bd
be564292f00c5bf0d7251c11f1c9618eb1117762
2 changes: 1 addition & 1 deletion MoltenVK/MoltenVK/API/mvk_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ typedef struct {
* The initial value or this parameter is set by the
* MVK_CONFIG_TIMESTAMP_PERIOD_LOWPASS_ALPHA
* runtime environment variable or MoltenVK compile-time build setting.
* If neither is set, this parameter is set to 0.05 by default,
* If neither is set, this parameter is set to 1.0 by default,
* indicating that the timestampPeriod will vary relatively slowly,
* with the expectation that the app is querying this value infrequently.
*/
Expand Down
2 changes: 2 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCmdRendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,8 @@ class MVKCmdSetPrimitiveRestartEnable : public MVKCommand {

protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;

VkBool32 _primitiveRestartEnable;
};


Expand Down
14 changes: 4 additions & 10 deletions MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm
Original file line number Diff line number Diff line change
Expand Up @@ -524,19 +524,13 @@

VkResult MVKCmdSetPrimitiveRestartEnable::setContent(MVKCommandBuffer* cmdBuff,
VkBool32 primitiveRestartEnable) {
// Validate
// In Metal, primitive restart cannot be disabled.
// Just issue warning here, as it is very likely the app is not actually expecting
// to use primitive restart at all, and is just setting this as a "just-in-case",
// and forcing an error here would be unexpected to the app (including CTS).
if ( !primitiveRestartEnable ) {
reportWarning(VK_ERROR_FEATURE_NOT_PRESENT, "Metal does not support disabling primitive restart.");
}

_primitiveRestartEnable = primitiveRestartEnable;
return VK_SUCCESS;
}

void MVKCmdSetPrimitiveRestartEnable::encode(MVKCommandEncoder* cmdEncoder) {}
void MVKCmdSetPrimitiveRestartEnable::encode(MVKCommandEncoder* cmdEncoder) {
cmdEncoder->_renderingState.setPrimitiveRestartEnable(_primitiveRestartEnable, true);
}


#pragma mark -
Expand Down
3 changes: 3 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState {
void setViewports(const MVKArrayRef<VkViewport> viewports, uint32_t firstViewport, bool isDynamic);
void setScissors(const MVKArrayRef<VkRect2D> scissors, uint32_t firstScissor, bool isDynamic);

void setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable, bool isDynamic);

void setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable, bool isDynamic);

void beginMetalRenderPass() override;
Expand Down Expand Up @@ -345,6 +347,7 @@ class MVKRenderingCommandEncoderState : public MVKCommandEncoderState {
MVKRenderStateFlags _dirtyStates;
MVKRenderStateFlags _modifiedStates;
bool _mtlDepthBiasEnable[StateScope::Count] = {};
bool _mtlPrimitiveRestartEnable[StateScope::Count] = {};
bool _mtlRasterizerDiscardEnable[StateScope::Count] = {};
bool _cullBothFaces[StateScope::Count] = {};
};
Expand Down
16 changes: 16 additions & 0 deletions MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,11 @@
setContent(Scissors);
}

void MVKRenderingCommandEncoderState::setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable, bool isDynamic) {
bool mtlPrimitiveRestartEnable = static_cast<bool>(primitiveRestartEnable);
setContent(PrimitiveRestartEnable);
}

void MVKRenderingCommandEncoderState::setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable, bool isDynamic) {
bool mtlRasterizerDiscardEnable = static_cast<bool>(rasterizerDiscardEnable);
setContent(RasterizerDiscardEnable);
Expand Down Expand Up @@ -473,6 +478,17 @@
[rendEnc setStencilFrontReferenceValue: sr.frontFaceValue backReferenceValue: sr.backFaceValue];
}

// Validate
// In Metal, primitive restart cannot be disabled.
// Just issue warning here, as it is very likely the app is not actually expecting
// to use primitive restart at all, and is just setting this as a "just-in-case",
// and forcing an error here would be unexpected to the app (including CTS).
auto mtlPrimType = getPrimitiveType();
if (isDirty(PrimitiveRestartEnable) && !getContent(PrimitiveRestartEnable) &&
(mtlPrimType == MTLPrimitiveTypeTriangleStrip || mtlPrimType == MTLPrimitiveTypeLineStrip)) {
reportWarning(VK_ERROR_FEATURE_NOT_PRESENT, "Metal does not support disabling primitive restart.");
}

if (isDirty(Viewports)) {
auto& mtlViewports = getContent(Viewports);
if (_cmdEncoder->_pDeviceFeatures->multiViewport) {
Expand Down
9 changes: 7 additions & 2 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,8 @@

// Basic lowpass filter TPout = (1 - A)TPout + (A * TPin).
// The lower A is, the slower TPout will change over time.
float a = mvkConfig().timestampPeriodLowPassAlpha;
// First time through, just use the measured value directly.
float a = earlierCPUTs ? mvkConfig().timestampPeriodLowPassAlpha : 1.0;
_properties.limits.timestampPeriod = ((1.0 - a) * _properties.limits.timestampPeriod) + (a * tsPeriod);
}
}
Expand Down Expand Up @@ -1711,7 +1712,11 @@
_metalFeatures.maxPerStageStorageTextureCount = 8;

_metalFeatures.vertexStrideAlignment = supportsMTLGPUFamily(Apple5) ? 1 : 4;

#if MVK_XCODE_15
// Dynamic vertex stride needs to have everything aligned - compiled with support for vertex stride calls, and supported by both runtime OS and GPU.
_metalFeatures.dynamicVertexStride = mvkOSVersionIsAtLeast(14.0, 17.0, 1.0) && (supportsMTLGPUFamily(Apple4) || supportsMTLGPUFamily(Mac2));
#endif

// GPU-specific features
switch (_properties.vendorID) {
Expand Down Expand Up @@ -2635,7 +2640,7 @@
_properties.limits.optimalBufferCopyRowPitchAlignment = 1;

_properties.limits.timestampComputeAndGraphics = VK_TRUE;
_properties.limits.timestampPeriod = mvkGetTimestampPeriod(); // Will be 1.0 on Apple Silicon
_properties.limits.timestampPeriod = 1.0; // On non-Apple GPU's, this can vary over time, and is calculated based on actual GPU activity.

_properties.limits.pointSizeRange[0] = 1;
switch (_properties.vendorID) {
Expand Down
2 changes: 2 additions & 0 deletions MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ enum MVKRenderStateType {
DepthTestEnable,
DepthWriteEnable,
FrontFace,
LineWidth,
LogicOp,
LogicOpEnable,
PatchControlPoints,
Expand Down Expand Up @@ -426,6 +427,7 @@ class MVKGraphicsPipeline : public MVKPipeline {
uint32_t _tessCtlPatchOutputBufferIndex = 0;
uint32_t _tessCtlLevelBufferIndex = 0;

bool _primitiveRestartEnable = true;
bool _hasRasterInfo = false;
bool _needsVertexSwizzleBuffer = false;
bool _needsVertexBufferSizeBuffer = false;
Expand Down
98 changes: 48 additions & 50 deletions MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@

// Rasterization
cmdEncoder->_renderingState.setPrimitiveTopology(_vkPrimitiveTopology, false);
cmdEncoder->_renderingState.setPrimitiveRestartEnable(_primitiveRestartEnable, false);
cmdEncoder->_renderingState.setBlendConstants(_blendConstants, false);
cmdEncoder->_renderingState.setStencilReferenceValues(_depthStencilInfo);
cmdEncoder->_renderingState.setViewports(_viewports.contents(), 0, false);
Expand Down Expand Up @@ -507,13 +508,7 @@
? pCreateInfo->pInputAssemblyState->topology
: VK_PRIMITIVE_TOPOLOGY_POINT_LIST);

// In Metal, primitive restart cannot be disabled.
// Just issue warning here, as it is very likely the app is not actually expecting
// to use primitive restart at all, and is just setting this as a "just-in-case",
// and forcing an error here would be unexpected to the app (including CTS).
if (pCreateInfo->pInputAssemblyState && !pCreateInfo->pInputAssemblyState->primitiveRestartEnable) {
reportWarning(VK_ERROR_FEATURE_NOT_PRESENT, "vkCreateGraphicsPipeline(): Metal does not support disabling primitive restart.");
}
_primitiveRestartEnable = pCreateInfo->pInputAssemblyState ? pCreateInfo->pInputAssemblyState->primitiveRestartEnable : true;

// Rasterization
_hasRasterInfo = mvkSetOrClear(&_rasterInfo, pCreateInfo->pRasterizationState);
Expand Down Expand Up @@ -560,6 +555,7 @@ static MVKRenderStateType getRenderStateType(VkDynamicState vkDynamicState) {
case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE: return DepthTestEnable;
case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE: return DepthWriteEnable;
case VK_DYNAMIC_STATE_FRONT_FACE: return FrontFace;
case VK_DYNAMIC_STATE_LINE_WIDTH: return LineWidth;
case VK_DYNAMIC_STATE_LOGIC_OP_EXT: return LogicOp;
case VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT: return LogicOpEnable;
case VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT: return PatchControlPoints;
Expand Down Expand Up @@ -1366,18 +1362,16 @@ static MTLVertexFormat mvkAdjustFormatVectorToSize(MTLVertexFormat format, uint3
const VkVertexInputBindingDescription* pVKVB = &pVI->pVertexBindingDescriptions[i];
if (shaderConfig.isVertexBufferUsed(pVKVB->binding)) {

// Vulkan allows any stride, but Metal only allows multiples of 4.
// TODO: We could try to expand the buffer to the required alignment in that case.
VkDeviceSize mtlVtxStrideAlignment = _device->_pMetalFeatures->vertexStrideAlignment;
if ((pVKVB->stride % mtlVtxStrideAlignment) != 0) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Under Metal, vertex attribute binding strides must be aligned to %llu bytes.", mtlVtxStrideAlignment));
// Vulkan allows any stride, but Metal requires multiples of 4 on older GPUs.
if (isVtxStrideStatic && (pVKVB->stride % _device->_pMetalFeatures->vertexStrideAlignment) != 0) {
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED, "Under Metal, vertex attribute binding strides must be aligned to %llu bytes.", _device->_pMetalFeatures->vertexStrideAlignment));
return false;
}

maxBinding = max(pVKVB->binding, maxBinding);
uint32_t vbIdx = getMetalBufferIndexForVertexAttributeBinding(pVKVB->binding);
auto vbDesc = inputDesc.layouts[vbIdx];
if (pVKVB->stride == 0) {
if (isVtxStrideStatic && pVKVB->stride == 0) {
// Stride can't be 0, it will be set later to attributes' maximum offset + size
// to prevent it from being larger than the underlying buffer permits.
vbDesc.stride = 0;
Expand Down Expand Up @@ -1418,52 +1412,54 @@ static MTLVertexFormat mvkAdjustFormatVectorToSize(MTLVertexFormat format, uint3
if (shaderConfig.isShaderInputLocationUsed(pVKVA->location)) {
uint32_t vaBinding = pVKVA->binding;
uint32_t vaOffset = pVKVA->offset;
auto vaDesc = inputDesc.attributes[pVKVA->location];
auto mtlFormat = (decltype(vaDesc.format))getPixelFormats()->getMTLVertexFormat(pVKVA->format);

// Vulkan allows offsets to exceed the buffer stride, but Metal doesn't.
// If this is the case, fetch a translated artificial buffer binding, using the same MTLBuffer,
// but that is translated so that the reduced VA offset fits into the binding stride.
const VkVertexInputBindingDescription* pVKVB = pVI->pVertexBindingDescriptions;
uint32_t attrSize = 0;
for (uint32_t j = 0; j < vbCnt; j++, pVKVB++) {
if (pVKVB->binding == pVKVA->binding) {
attrSize = getPixelFormats()->getBytesPerBlock(pVKVA->format);
if (pVKVB->stride == 0) {
// The step is set to constant, but we need to change stride to be non-zero for metal.
// Look for the maximum offset + size to set as the stride.
uint32_t vbIdx = getMetalBufferIndexForVertexAttributeBinding(pVKVB->binding);
auto vbDesc = inputDesc.layouts[vbIdx];
uint32_t strideLowBound = vaOffset + attrSize;
if (vbDesc.stride < strideLowBound) vbDesc.stride = strideLowBound;
} else if (vaOffset && vaOffset + attrSize > pVKVB->stride) {
// Move vertex attribute offset into the stride. This vertex attribute may be
// combined with other vertex attributes into the same translated buffer binding.
// But if the reduced offset combined with the vertex attribute size still won't
// fit into the buffer binding stride, force the vertex attribute offset to zero,
// effectively dedicating this vertex attribute to its own buffer binding.
uint32_t origOffset = vaOffset;
vaOffset %= pVKVB->stride;
if (vaOffset + attrSize > pVKVB->stride) {
vaOffset = 0;
if (isVtxStrideStatic) {
const VkVertexInputBindingDescription* pVKVB = pVI->pVertexBindingDescriptions;
uint32_t attrSize = 0;
for (uint32_t j = 0; j < vbCnt; j++, pVKVB++) {
if (pVKVB->binding == pVKVA->binding) {
attrSize = getPixelFormats()->getBytesPerBlock(pVKVA->format);
if (pVKVB->stride == 0) {
// The step is set to constant, but we need to change stride to be non-zero for metal.
// Look for the maximum offset + size to set as the stride.
uint32_t vbIdx = getMetalBufferIndexForVertexAttributeBinding(pVKVB->binding);
auto vbDesc = inputDesc.layouts[vbIdx];
uint32_t strideLowBound = vaOffset + attrSize;
if (vbDesc.stride < strideLowBound) vbDesc.stride = strideLowBound;
} else if (vaOffset && vaOffset + attrSize > pVKVB->stride) {
// Move vertex attribute offset into the stride. This vertex attribute may be
// combined with other vertex attributes into the same translated buffer binding.
// But if the reduced offset combined with the vertex attribute size still won't
// fit into the buffer binding stride, force the vertex attribute offset to zero,
// effectively dedicating this vertex attribute to its own buffer binding.
uint32_t origOffset = vaOffset;
vaOffset %= pVKVB->stride;
if (vaOffset + attrSize > pVKVB->stride) {
vaOffset = 0;
}
vaBinding = getTranslatedVertexBinding(vaBinding, origOffset - vaOffset, maxBinding);
if (zeroDivisorBindings.count(pVKVB->binding)) {
zeroDivisorBindings.insert(vaBinding);
}
}
vaBinding = getTranslatedVertexBinding(vaBinding, origOffset - vaOffset, maxBinding);
if (zeroDivisorBindings.count(pVKVB->binding)) {
zeroDivisorBindings.insert(vaBinding);
}
break;
}
break;
}
if (pVKVB->stride && attrSize > pVKVB->stride) {
/* Metal does not support overlapping loads. Truncate format vector length to prevent an assertion
* and hope it's not used by the shader. */
MTLVertexFormat newFormat = mvkAdjustFormatVectorToSize((MTLVertexFormat)mtlFormat, pVKVB->stride);
reportError(VK_SUCCESS, "Found attribute with size (%u) larger than it's binding's stride (%u). Changing descriptor format from %s to %s.",
attrSize, pVKVB->stride, getPixelFormats()->getName((MTLVertexFormat)mtlFormat), getPixelFormats()->getName(newFormat));
mtlFormat = (decltype(vaDesc.format))newFormat;
}
}

auto vaDesc = inputDesc.attributes[pVKVA->location];
auto mtlFormat = (decltype(vaDesc.format))getPixelFormats()->getMTLVertexFormat(pVKVA->format);
if (pVKVB->stride && attrSize > pVKVB->stride) {
/* Metal does not support overlapping loads. Truncate format vector length to prevent an assertion
* and hope it's not used by the shader. */
MTLVertexFormat newFormat = mvkAdjustFormatVectorToSize((MTLVertexFormat)mtlFormat, pVKVB->stride);
reportError(VK_SUCCESS, "Found attribute with size (%u) larger than it's binding's stride (%u). Changing descriptor format from %s to %s.",
attrSize, pVKVB->stride, getPixelFormats()->getName((MTLVertexFormat)mtlFormat), getPixelFormats()->getName(newFormat));
mtlFormat = (decltype(vaDesc.format))newFormat;
}
vaDesc.format = mtlFormat;
vaDesc.bufferIndex = (decltype(vaDesc.bufferIndex))getMetalBufferIndexForVertexAttributeBinding(vaBinding);
vaDesc.offset = vaOffset;
Expand Down Expand Up @@ -1733,6 +1729,7 @@ static MTLVertexFormat mvkAdjustFormatVectorToSize(MTLVertexFormat format, uint3
shaderConfig.options.mslOptions.multiview = mvkIsMultiview(pRendInfo->viewMask);
shaderConfig.options.mslOptions.multiview_layered_rendering = getPhysicalDevice()->canUseInstancingForMultiview();
shaderConfig.options.mslOptions.view_index_from_device_index = mvkAreAllFlagsEnabled(pCreateInfo->flags, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT);
shaderConfig.options.mslOptions.replace_recursive_inputs = mvkOSVersionIsAtLeast(14.0, 17.0, 1.0);
#if MVK_MACOS
shaderConfig.options.mslOptions.emulate_subgroups = !_device->_pMetalFeatures->simdPermute;
#endif
Expand Down Expand Up @@ -2138,6 +2135,7 @@ static MTLVertexFormat mvkAdjustFormatVectorToSize(MTLVertexFormat format, uint3
shaderConfig.options.mslOptions.buffer_size_buffer_index = _bufferSizeBufferIndex.stages[kMVKShaderStageCompute];
shaderConfig.options.mslOptions.dynamic_offsets_buffer_index = _dynamicOffsetBufferIndex.stages[kMVKShaderStageCompute];
shaderConfig.options.mslOptions.indirect_params_buffer_index = _indirectParamsIndex.stages[kMVKShaderStageCompute];
shaderConfig.options.mslOptions.replace_recursive_inputs = mvkOSVersionIsAtLeast(14.0, 17.0, 1.0);

MVKMTLFunction func = ((MVKShaderModule*)pSS->module)->getMTLFunction(&shaderConfig, pSS->pSpecializationInfo, this, pStageFB);
if ( !func.getMTLFunction() ) {
Expand Down
Loading

0 comments on commit ddb725c

Please sign in to comment.