From f4423428e3b0d1034130451d666ebdf7d63dbaff Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Tue, 10 Oct 2023 12:19:15 -0400 Subject: [PATCH] Add support for VK_EXT_extended_dynamic_state2 extension. - Add MVKPipelineCommandEncoderState subclasses MVKGraphicsPipelineCommandEncoderState & MVKComputePipelineCommandEncoderState, track patch control points in MVKGraphicsPipelineCommandEncoderState, and add getGraphicsPipeline() & getComputePipeline() to simplify casting. - Rename MVKRasterizingCommandEncoderState to MVKRenderingCommandEncoderState, and MVKCommandEncoder::_rasterizingState to _renderingState. - Rename MVKCmdRenderPass.h/mm to MVKCmdRendering.h/mm. - Move MVKCmdExecuteCommands from MVKCmdRenderPass.h/mm to MVKCmdPipeline.h/mm. - While working on vkCmdSetLogicOpEXT(), add support for vkCmdSetLogicOpEnableEXT() from VK_EXT_extended_dynamic_state3. --- Docs/MoltenVK_Runtime_UserGuide.md | 3 +- Docs/Whats_New.md | 3 +- MoltenVK/MoltenVK.xcodeproj/project.pbxproj | 40 ++--- MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm | 2 +- MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm | 28 ++-- MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h | 28 ++++ MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm | 27 ++++ .../{MVKCmdRenderPass.h => MVKCmdRendering.h} | 138 +++++++++++++---- ...MVKCmdRenderPass.mm => MVKCmdRendering.mm} | 140 +++++++++++++----- MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm | 2 +- MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h | 8 +- .../MoltenVK/Commands/MVKCommandBuffer.mm | 10 +- .../Commands/MVKCommandEncoderState.h | 58 ++++++-- .../Commands/MVKCommandEncoderState.mm | 79 ++++++---- MoltenVK/MoltenVK/Commands/MVKCommandPool.h | 2 +- .../MoltenVK/Commands/MVKCommandTypePools.def | 8 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 7 + .../GPUObjects/MVKDeviceFeatureStructs.def | 1 + MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 3 + MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h | 12 +- MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm | 54 ++++--- MoltenVK/MoltenVK/Layers/MVKExtensions.def | 1 + MoltenVK/MoltenVK/Vulkan/vulkan.mm | 67 ++++++++- 23 files changed, 541 insertions(+), 180 deletions(-) rename MoltenVK/MoltenVK/Commands/{MVKCmdRenderPass.h => MVKCmdRendering.h} (86%) rename MoltenVK/MoltenVK/Commands/{MVKCmdRenderPass.mm => MVKCmdRendering.mm} (82%) diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md index 27ed0c2e..79f3f1a5 100644 --- a/Docs/MoltenVK_Runtime_UserGuide.md +++ b/Docs/MoltenVK_Runtime_UserGuide.md @@ -363,7 +363,8 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll - `VK_EXT_descriptor_indexing` *(initial release limited to Metal Tier 1: 96/128 textures, 16 samplers, except macOS 11.0 (Big Sur) or later, or on older versions of macOS using an Intel GPU, and if Metal argument buffers enabled in config)* -- `VK_EXT_extended_dynamic_state` *(requires Metal 3.1)* +- `VK_EXT_extended_dynamic_state` *(requires Metal 3.1 for `VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE`)* +- `VK_EXT_extended_dynamic_state2` - `VK_EXT_external_memory_host` - `VK_EXT_fragment_shader_interlock` *(requires Metal 2.0 and Raster Order Groups)* - `VK_EXT_host_query_reset` diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 6da6eb0c..6ab13f7a 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -20,7 +20,8 @@ Released TBD - Add support for extensions: - `VK_KHR_synchronization2` - - `VK_EXT_extended_dynamic_state` + - `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. - Ensure objects retained for life of `MTLCommandBuffer` during `vkCmdBlitImage()` & `vkQueuePresentKHR()`. diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj index 1dffab36..46ff50fc 100644 --- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj +++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj @@ -46,7 +46,7 @@ 2FEA0A6724902F9F00EEF3AD /* MVKCommonEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */; }; 2FEA0A6824902F9F00EEF3AD /* MVKWatermark.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149491FB6A3F7005F00B4 /* MVKWatermark.h */; }; 2FEA0A6924902F9F00EEF3AD /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */; }; - 2FEA0A6A24902F9F00EEF3AD /* MVKCmdRenderPass.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */; }; + 2FEA0A6A24902F9F00EEF3AD /* MVKCmdRendering.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */; }; 2FEA0A6B24902F9F00EEF3AD /* MVKCmdPipeline.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB76E1C7DFB4800632CA3 /* MVKCmdPipeline.h */; }; 2FEA0A6C24902F9F00EEF3AD /* MVKSmallVectorAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */; }; 2FEA0A6D24902F9F00EEF3AD /* MVKPipeline.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB78D1C7DFB4800632CA3 /* MVKPipeline.h */; }; @@ -90,7 +90,7 @@ 2FEA0A9424902F9F00EEF3AD /* MVKCommandPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB77B1C7DFB4800632CA3 /* MVKCommandPool.mm */; }; 2FEA0A9524902F9F00EEF3AD /* MVKCmdDraw.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */; }; 2FEA0A9624902F9F00EEF3AD /* MVKCommandBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7791C7DFB4800632CA3 /* MVKCommandBuffer.mm */; }; - 2FEA0A9724902F9F00EEF3AD /* MVKCmdRenderPass.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */; }; + 2FEA0A9724902F9F00EEF3AD /* MVKCmdRendering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */; }; 2FEA0A9824902F9F00EEF3AD /* MVKBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7801C7DFB4800632CA3 /* MVKBuffer.mm */; }; 2FEA0A9924902F9F00EEF3AD /* mvk_datatypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7A91C7DFB4800632CA3 /* mvk_datatypes.mm */; }; 2FEA0A9A24902F9F00EEF3AD /* MVKExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A909F65E213B190700FCD6BE /* MVKExtensions.mm */; }; @@ -172,10 +172,10 @@ A94FB7C11C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7701C7DFB4800632CA3 /* MVKCmdQueries.h */; }; A94FB7C21C7DFB4800632CA3 /* MVKCmdQueries.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */; }; A94FB7C31C7DFB4800632CA3 /* MVKCmdQueries.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */; }; - A94FB7C41C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */; }; - A94FB7C51C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */; }; - A94FB7C61C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */; }; - A94FB7C71C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */; }; + A94FB7C41C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */; }; + A94FB7C51C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */; }; + A94FB7C61C7DFB4800632CA3 /* MVKCmdRendering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */; }; + A94FB7C71C7DFB4800632CA3 /* MVKCmdRendering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */; }; A94FB7C81C7DFB4800632CA3 /* MVKCmdDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7741C7DFB4800632CA3 /* MVKCmdDraw.h */; }; A94FB7C91C7DFB4800632CA3 /* MVKCmdDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7741C7DFB4800632CA3 /* MVKCmdDraw.h */; }; A94FB7CA1C7DFB4800632CA3 /* MVKCmdDraw.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */; }; @@ -420,7 +420,7 @@ DCFD7F0B2A45BC6E007BBBF7 /* MVKCommonEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */; }; DCFD7F0C2A45BC6E007BBBF7 /* MVKWatermark.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149491FB6A3F7005F00B4 /* MVKWatermark.h */; }; DCFD7F0D2A45BC6E007BBBF7 /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */; }; - DCFD7F0E2A45BC6E007BBBF7 /* MVKCmdRenderPass.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */; }; + DCFD7F0E2A45BC6E007BBBF7 /* MVKCmdRendering.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */; }; DCFD7F0F2A45BC6E007BBBF7 /* MVKCmdPipeline.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB76E1C7DFB4800632CA3 /* MVKCmdPipeline.h */; }; DCFD7F102A45BC6E007BBBF7 /* MVKSmallVectorAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */; }; DCFD7F112A45BC6E007BBBF7 /* MVKPipeline.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB78D1C7DFB4800632CA3 /* MVKPipeline.h */; }; @@ -466,7 +466,7 @@ DCFD7F3A2A45BC6E007BBBF7 /* MVKCommandPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB77B1C7DFB4800632CA3 /* MVKCommandPool.mm */; }; DCFD7F3B2A45BC6E007BBBF7 /* MVKCmdDraw.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */; }; DCFD7F3C2A45BC6E007BBBF7 /* MVKCommandBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7791C7DFB4800632CA3 /* MVKCommandBuffer.mm */; }; - DCFD7F3D2A45BC6E007BBBF7 /* MVKCmdRenderPass.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */; }; + DCFD7F3D2A45BC6E007BBBF7 /* MVKCmdRendering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */; }; DCFD7F3E2A45BC6E007BBBF7 /* MVKBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7801C7DFB4800632CA3 /* MVKBuffer.mm */; }; DCFD7F3F2A45BC6E007BBBF7 /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; }; DCFD7F402A45BC6E007BBBF7 /* mvk_datatypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7A91C7DFB4800632CA3 /* mvk_datatypes.mm */; }; @@ -595,8 +595,8 @@ A94FB76F1C7DFB4800632CA3 /* MVKCmdPipeline.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdPipeline.mm; sourceTree = ""; }; A94FB7701C7DFB4800632CA3 /* MVKCmdQueries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdQueries.h; sourceTree = ""; }; A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdQueries.mm; sourceTree = ""; }; - A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdRenderPass.h; sourceTree = ""; }; - A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdRenderPass.mm; sourceTree = ""; }; + A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdRendering.h; sourceTree = ""; }; + A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdRendering.mm; sourceTree = ""; }; A94FB7741C7DFB4800632CA3 /* MVKCmdDraw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdDraw.h; sourceTree = ""; }; A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdDraw.mm; sourceTree = ""; }; A94FB7761C7DFB4800632CA3 /* MVKCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCommand.h; sourceTree = ""; }; @@ -744,8 +744,8 @@ A94FB76F1C7DFB4800632CA3 /* MVKCmdPipeline.mm */, A94FB7701C7DFB4800632CA3 /* MVKCmdQueries.h */, A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */, - A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */, - A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */, + A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */, + A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */, A94FB76C1C7DFB4800632CA3 /* MVKCmdTransfer.h */, A94FB76D1C7DFB4800632CA3 /* MVKCmdTransfer.mm */, A94FB7761C7DFB4800632CA3 /* MVKCommand.h */, @@ -995,7 +995,7 @@ 2FEA0A6724902F9F00EEF3AD /* MVKCommonEnvironment.h in Headers */, 2FEA0A6824902F9F00EEF3AD /* MVKWatermark.h in Headers */, 2FEA0A6924902F9F00EEF3AD /* MVKOSExtensions.h in Headers */, - 2FEA0A6A24902F9F00EEF3AD /* MVKCmdRenderPass.h in Headers */, + 2FEA0A6A24902F9F00EEF3AD /* MVKCmdRendering.h in Headers */, 2FEA0A6B24902F9F00EEF3AD /* MVKCmdPipeline.h in Headers */, 2FEA0A6C24902F9F00EEF3AD /* MVKSmallVectorAllocator.h in Headers */, 2FEA0A6D24902F9F00EEF3AD /* MVKPipeline.h in Headers */, @@ -1074,7 +1074,7 @@ A9F042A41FB4CF83009FCCB8 /* MVKCommonEnvironment.h in Headers */, A981495D1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */, A9B51BD9225E986A00AC74D2 /* MVKOSExtensions.h in Headers */, - A94FB7C41C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */, + A94FB7C41C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */, A94FB7BC1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */, A9F3D9DC24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */, A9C327562AAFBD390025EE79 /* MVKConfigMembers.def in Headers */, @@ -1151,7 +1151,7 @@ A9F042A51FB4CF83009FCCB8 /* MVKCommonEnvironment.h in Headers */, A981495E1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */, A9B51BDA225E986A00AC74D2 /* MVKOSExtensions.h in Headers */, - A94FB7C51C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */, + A94FB7C51C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */, A94FB7BD1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */, A9F3D9DD24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */, A94FB7F91C7DFB4800632CA3 /* MVKPipeline.h in Headers */, @@ -1228,7 +1228,7 @@ DCFD7F0B2A45BC6E007BBBF7 /* MVKCommonEnvironment.h in Headers */, DCFD7F0C2A45BC6E007BBBF7 /* MVKWatermark.h in Headers */, DCFD7F0D2A45BC6E007BBBF7 /* MVKOSExtensions.h in Headers */, - DCFD7F0E2A45BC6E007BBBF7 /* MVKCmdRenderPass.h in Headers */, + DCFD7F0E2A45BC6E007BBBF7 /* MVKCmdRendering.h in Headers */, DCFD7F0F2A45BC6E007BBBF7 /* MVKCmdPipeline.h in Headers */, DCFD7F102A45BC6E007BBBF7 /* MVKSmallVectorAllocator.h in Headers */, DCFD7F112A45BC6E007BBBF7 /* MVKPipeline.h in Headers */, @@ -1674,7 +1674,7 @@ 2FEA0A9424902F9F00EEF3AD /* MVKCommandPool.mm in Sources */, 2FEA0A9524902F9F00EEF3AD /* MVKCmdDraw.mm in Sources */, 2FEA0A9624902F9F00EEF3AD /* MVKCommandBuffer.mm in Sources */, - 2FEA0A9724902F9F00EEF3AD /* MVKCmdRenderPass.mm in Sources */, + 2FEA0A9724902F9F00EEF3AD /* MVKCmdRendering.mm in Sources */, 2FEA0A9824902F9F00EEF3AD /* MVKBuffer.mm in Sources */, 2FEA0A9924902F9F00EEF3AD /* mvk_datatypes.mm in Sources */, 2FEA0A9A24902F9F00EEF3AD /* MVKExtensions.mm in Sources */, @@ -1734,7 +1734,7 @@ A94FB7D61C7DFB4800632CA3 /* MVKCommandPool.mm in Sources */, A94FB7CA1C7DFB4800632CA3 /* MVKCmdDraw.mm in Sources */, A94FB7D21C7DFB4800632CA3 /* MVKCommandBuffer.mm in Sources */, - A94FB7C61C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */, + A94FB7C61C7DFB4800632CA3 /* MVKCmdRendering.mm in Sources */, A94FB7DE1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */, A9A5E9C725C0822700E9085E /* MVKEnvironment.cpp in Sources */, A94FB82A1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */, @@ -1794,7 +1794,7 @@ A94FB7D71C7DFB4800632CA3 /* MVKCommandPool.mm in Sources */, A94FB7CB1C7DFB4800632CA3 /* MVKCmdDraw.mm in Sources */, A94FB7D31C7DFB4800632CA3 /* MVKCommandBuffer.mm in Sources */, - A94FB7C71C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */, + A94FB7C71C7DFB4800632CA3 /* MVKCmdRendering.mm in Sources */, A94FB7DF1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */, A9A5E9C925C0822700E9085E /* MVKEnvironment.cpp in Sources */, A94FB82B1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */, @@ -1854,7 +1854,7 @@ DCFD7F3A2A45BC6E007BBBF7 /* MVKCommandPool.mm in Sources */, DCFD7F3B2A45BC6E007BBBF7 /* MVKCmdDraw.mm in Sources */, DCFD7F3C2A45BC6E007BBBF7 /* MVKCommandBuffer.mm in Sources */, - DCFD7F3D2A45BC6E007BBBF7 /* MVKCmdRenderPass.mm in Sources */, + DCFD7F3D2A45BC6E007BBBF7 /* MVKCmdRendering.mm in Sources */, DCFD7F3E2A45BC6E007BBBF7 /* MVKBuffer.mm in Sources */, DCFD7F3F2A45BC6E007BBBF7 /* MVKEnvironment.cpp in Sources */, DCFD7F402A45BC6E007BBBF7 /* mvk_datatypes.mm in Sources */, diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm index 1125963d..020f04b5 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.mm @@ -46,7 +46,7 @@ void MVKCmdDispatch::encode(MVKCommandEncoder* cmdEncoder) { MTLRegion mtlThreadgroupCount = MTLRegionMake3D(_baseGroupX, _baseGroupY, _baseGroupZ, _groupCountX, _groupCountY, _groupCountZ); cmdEncoder->finalizeDispatchState(); // Ensure all updated state has been submitted to Metal id mtlEncoder = cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch); - auto* pipeline = (MVKComputePipeline*)cmdEncoder->_computePipelineState.getPipeline(); + auto* pipeline = cmdEncoder->_computePipelineState.getComputePipeline(); if (pipeline->allowsDispatchBase()) { if ([mtlEncoder respondsToSelector: @selector(setStageInRegion:)]) { // We'll use the stage-input region to pass the base along to the shader. diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm b/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm index a1b71512..a7930a47 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdDraw.mm @@ -149,7 +149,7 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) { return; } - auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline(); + auto* pipeline = cmdEncoder->_graphicsPipelineState.getGraphicsPipeline(); // Metal doesn't support triangle fans, so encode it as triangles via an indexed indirect triangles command instead. if (pipeline->getVkPrimitiveTopology() == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) { @@ -172,7 +172,7 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) { } tessParams; uint32_t outControlPointCount = 0; if (pipeline->isTessellationPipeline()) { - tessParams.inControlPointCount = pipeline->getInputControlPointCount(); + tessParams.inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints(); outControlPointCount = pipeline->getOutputControlPointCount(); tessParams.patchCount = mvkCeilingDivide(_vertexCount, tessParams.inControlPointCount) * _instanceCount; } @@ -299,13 +299,13 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) { uint32_t instanceCount = _instanceCount * viewCount; cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _firstInstance); if (cmdEncoder->_pDeviceMetalFeatures->baseVertexInstanceDrawing) { - [cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_rasterizingState.getPrimitiveType() + [cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_renderingState.getPrimitiveType() vertexStart: _firstVertex vertexCount: _vertexCount instanceCount: instanceCount baseInstance: _firstInstance]; } else { - [cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_rasterizingState.getPrimitiveType() + [cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_renderingState.getPrimitiveType() vertexStart: _firstVertex vertexCount: _vertexCount instanceCount: instanceCount]; @@ -374,7 +374,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) { return; } - auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline(); + auto* pipeline = cmdEncoder->_graphicsPipelineState.getGraphicsPipeline(); // Metal doesn't support triangle fans, so encode it as triangles via an indexed indirect triangles command instead. if (pipeline->getVkPrimitiveTopology() == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) { @@ -401,7 +401,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) { } tessParams; uint32_t outControlPointCount = 0; if (pipeline->isTessellationPipeline()) { - tessParams.inControlPointCount = pipeline->getInputControlPointCount(); + tessParams.inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints(); outControlPointCount = pipeline->getOutputControlPointCount(); tessParams.patchCount = mvkCeilingDivide(_indexCount, tessParams.inControlPointCount) * _instanceCount; } @@ -533,7 +533,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) { uint32_t instanceCount = _instanceCount * viewCount; cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _firstInstance); if (cmdEncoder->_pDeviceMetalFeatures->baseVertexInstanceDrawing) { - [cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_rasterizingState.getPrimitiveType() + [cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_renderingState.getPrimitiveType() indexCount: _indexCount indexType: (MTLIndexType)ibb.mtlIndexType indexBuffer: ibb.mtlBuffer @@ -542,7 +542,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) { baseVertex: _vertexOffset baseInstance: _firstInstance]; } else { - [cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_rasterizingState.getPrimitiveType() + [cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_renderingState.getPrimitiveType() indexCount: _indexCount indexType: (MTLIndexType)ibb.mtlIndexType indexBuffer: ibb.mtlBuffer @@ -649,7 +649,7 @@ void MVKCmdDrawIndirect::encodeIndexedIndirect(MVKCommandEncoder* cmdEncoder) { void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) { - auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline(); + auto* pipeline = cmdEncoder->_graphicsPipelineState.getGraphicsPipeline(); // Metal doesn't support triangle fans, so encode it as indexed indirect triangles instead. if (pipeline->getVkPrimitiveTopology() == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) { @@ -686,7 +686,7 @@ void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) { // encoding and execution. So we don't know how big to make the buffers. // We must assume an arbitrarily large number of vertices may be submitted. // But not too many, or we'll exhaust available VRAM. - inControlPointCount = pipeline->getInputControlPointCount(); + inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints(); outControlPointCount = pipeline->getOutputControlPointCount(); vertexCount = kMVKMaxDrawIndirectVertexCount; patchCount = mvkCeilingDivide(vertexCount, inControlPointCount); @@ -928,7 +928,7 @@ void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) { cmdEncoder->_graphicsResourcesState.beginMetalRenderPass(); cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->beginMetalRenderPass(); } else { - [cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_rasterizingState.getPrimitiveType() + [cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_renderingState.getPrimitiveType() indirectBuffer: mtlIndBuff indirectBufferOffset: mtlIndBuffOfst]; mtlIndBuffOfst += needsInstanceAdjustment ? sizeof(MTLDrawPrimitivesIndirectArguments) : _mtlIndirectBufferStride; @@ -999,7 +999,7 @@ void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder, const MVKI MVKIndexMTLBufferBinding ibb = ibbOrig; MVKIndexMTLBufferBinding ibbTriFan = ibb; - auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline(); + auto* pipeline = cmdEncoder->_graphicsPipelineState.getGraphicsPipeline(); MVKVertexAdjustments vtxAdjmts; vtxAdjmts.mtlIndexType = ibb.mtlIndexType; @@ -1034,7 +1034,7 @@ void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder, const MVKI // encoding and execution. So we don't know how big to make the buffers. // We must assume an arbitrarily large number of vertices may be submitted. // But not too many, or we'll exhaust available VRAM. - inControlPointCount = pipeline->getInputControlPointCount(); + inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints(); outControlPointCount = pipeline->getOutputControlPointCount(); vertexCount = kMVKMaxDrawIndirectVertexCount; patchCount = mvkCeilingDivide(vertexCount, inControlPointCount); @@ -1315,7 +1315,7 @@ void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder, const MVKI cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->beginMetalRenderPass(); } else { cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _directCmdFirstInstance); - [cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_rasterizingState.getPrimitiveType() + [cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_renderingState.getPrimitiveType() indexType: (MTLIndexType)ibb.mtlIndexType indexBuffer: ibb.mtlBuffer indexBufferOffset: ibb.offset diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h index aec8800c..84bc923a 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h @@ -30,6 +30,34 @@ class MVKDescriptorSet; class MVKDescriptorUpdateTemplate; +#pragma mark - +#pragma mark MVKCmdExecuteCommands + +/** + * Vulkan command to execute secondary command buffers. + * Template class to balance vector pre-allocations between very common low counts and fewer larger counts. + */ +template +class MVKCmdExecuteCommands : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + uint32_t commandBuffersCount, + const VkCommandBuffer* pCommandBuffers); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + MVKSmallVector _secondaryCommandBuffers; +}; + +// Concrete template class implementations. +typedef MVKCmdExecuteCommands<1> MVKCmdExecuteCommands1; +typedef MVKCmdExecuteCommands<16> MVKCmdExecuteCommandsMulti; + + #pragma mark - #pragma mark MVKCmdPipelineBarrier diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm index 05e578f6..1a30f550 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm @@ -26,6 +26,33 @@ #include "mvk_datatypes.hpp" +#pragma mark - +#pragma mark MVKCmdExecuteCommands + +template +VkResult MVKCmdExecuteCommands::setContent(MVKCommandBuffer* cmdBuff, + uint32_t commandBuffersCount, + const VkCommandBuffer* pCommandBuffers) { + // Add clear values + _secondaryCommandBuffers.clear(); // Clear for reuse + _secondaryCommandBuffers.reserve(commandBuffersCount); + for (uint32_t cbIdx = 0; cbIdx < commandBuffersCount; cbIdx++) { + _secondaryCommandBuffers.push_back(MVKCommandBuffer::getMVKCommandBuffer(pCommandBuffers[cbIdx])); + } + cmdBuff->recordExecuteCommands(_secondaryCommandBuffers.contents()); + + return VK_SUCCESS; +} + +template +void MVKCmdExecuteCommands::encode(MVKCommandEncoder* cmdEncoder) { + for (auto& cb : _secondaryCommandBuffers) { cmdEncoder->encodeSecondary(cb); } +} + +template class MVKCmdExecuteCommands<1>; +template class MVKCmdExecuteCommands<16>; + + #pragma mark - #pragma mark MVKCmdPipelineBarrier diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h similarity index 86% rename from MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h rename to MoltenVK/MoltenVK/Commands/MVKCmdRendering.h index 1e3bae5c..2b11ae8e 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.h @@ -1,5 +1,5 @@ /* - * MVKCmdRenderPass.h + * MVKCmdRendering.h * * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) * @@ -207,34 +207,6 @@ protected: }; -#pragma mark - -#pragma mark MVKCmdExecuteCommands - -/** - * Vulkan command to execute secondary command buffers. - * Template class to balance vector pre-allocations between very common low counts and fewer larger counts. - */ -template -class MVKCmdExecuteCommands : public MVKCommand { - -public: - VkResult setContent(MVKCommandBuffer* cmdBuff, - uint32_t commandBuffersCount, - const VkCommandBuffer* pCommandBuffers); - - void encode(MVKCommandEncoder* cmdEncoder) override; - -protected: - MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; - - MVKSmallVector _secondaryCommandBuffers; -}; - -// Concrete template class implementations. -typedef MVKCmdExecuteCommands<1> MVKCmdExecuteCommands1; -typedef MVKCmdExecuteCommands<16> MVKCmdExecuteCommandsMulti; - - #pragma mark - #pragma mark MVKCmdSetViewport @@ -337,6 +309,25 @@ protected: }; +#pragma mark - +#pragma mark MVKCmdSetDepthBiasEnable + +/** Vulkan command to dynamically enable or disable depth bias. */ +class MVKCmdSetDepthBiasEnable : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + VkBool32 depthBiasEnable); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + VkBool32 _depthBiasEnable; +}; + + #pragma mark - #pragma mark MVKCmdSetBlendConstants @@ -356,6 +347,40 @@ protected: }; +#pragma mark - +#pragma mark MVKCmdSetLogicOp + +/** Vulkan command to dynamically set the blending logic operation. */ +class MVKCmdSetLogicOp : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + VkLogicOp logicOp); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; +}; + + +#pragma mark - +#pragma mark MVKCmdSetLogicOpEnable + +/** Vulkan command to dynamically enable or disable the blending logic operation. */ +class MVKCmdSetLogicOpEnable : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + VkBool32 logicOpEnable); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; +}; + + #pragma mark - #pragma mark MVKCmdSetDepthTestEnable @@ -600,6 +625,25 @@ protected: }; +#pragma mark - +#pragma mark MVKCmdSetPatchControlPoints + +/** Vulkan command to dynamically set the number of patch control points. */ +class MVKCmdSetPatchControlPoints : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + uint32_t patchControlPoints); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + uint32_t _patchControlPoints; +}; + + #pragma mark - #pragma mark MVKCmdSetPrimitiveTopology @@ -618,3 +662,39 @@ protected: VkPrimitiveTopology _primitiveTopology; }; + +#pragma mark - +#pragma mark MVKCmdSetPrimitiveRestartEnable + +/** Vulkan command to dynamically enable or disable primitive restart functionality. */ +class MVKCmdSetPrimitiveRestartEnable : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + VkBool32 primitiveRestartEnable); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; +}; + + +#pragma mark - +#pragma mark MVKCmdSetRasterizerDiscardEnable + +/** Vulkan command to dynamically enable or disable rasterization. */ +class MVKCmdSetRasterizerDiscardEnable : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + VkBool32 rasterizerDiscardEnable); + + void encode(MVKCommandEncoder* cmdEncoder) override; + +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + VkBool32 _rasterizerDiscardEnable; +}; + diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm similarity index 82% rename from MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm rename to MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm index b5befc3a..33078a02 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdRendering.mm @@ -1,5 +1,5 @@ /* - * MVKCmdRenderPass.mm + * MVKCmdRendering.mm * * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) * @@ -16,7 +16,7 @@ * limitations under the License. */ -#include "MVKCmdRenderPass.h" +#include "MVKCmdRendering.h" #include "MVKCommandBuffer.h" #include "MVKCommandPool.h" #include "MVKFramebuffer.h" @@ -231,33 +231,6 @@ void MVKCmdSetSampleLocations::encode(MVKCommandEncoder* cmdEncoder) { } -#pragma mark - -#pragma mark MVKCmdExecuteCommands - -template -VkResult MVKCmdExecuteCommands::setContent(MVKCommandBuffer* cmdBuff, - uint32_t commandBuffersCount, - const VkCommandBuffer* pCommandBuffers) { - // Add clear values - _secondaryCommandBuffers.clear(); // Clear for reuse - _secondaryCommandBuffers.reserve(commandBuffersCount); - for (uint32_t cbIdx = 0; cbIdx < commandBuffersCount; cbIdx++) { - _secondaryCommandBuffers.push_back(MVKCommandBuffer::getMVKCommandBuffer(pCommandBuffers[cbIdx])); - } - cmdBuff->recordExecuteCommands(_secondaryCommandBuffers.contents()); - - return VK_SUCCESS; -} - -template -void MVKCmdExecuteCommands::encode(MVKCommandEncoder* cmdEncoder) { - for (auto& cb : _secondaryCommandBuffers) { cmdEncoder->encodeSecondary(cb); } -} - -template class MVKCmdExecuteCommands<1>; -template class MVKCmdExecuteCommands<16>; - - #pragma mark - #pragma mark MVKCmdSetViewport @@ -278,7 +251,7 @@ VkResult MVKCmdSetViewport::setContent(MVKCommandBuffer* cmdBuff, template void MVKCmdSetViewport::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->_rasterizingState.setViewports(_viewports.contents(), _firstViewport, true); + cmdEncoder->_renderingState.setViewports(_viewports.contents(), _firstViewport, true); } template class MVKCmdSetViewport<1>; @@ -305,7 +278,7 @@ VkResult MVKCmdSetScissor::setContent(MVKCommandBuffer* cmdBuff, template void MVKCmdSetScissor::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->_rasterizingState.setScissors(_scissors.contents(), _firstScissor, true); + cmdEncoder->_renderingState.setScissors(_scissors.contents(), _firstScissor, true); } template class MVKCmdSetScissor<1>; @@ -345,12 +318,26 @@ VkResult MVKCmdSetDepthBias::setContent(MVKCommandBuffer* cmdBuff, } void MVKCmdSetDepthBias::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->_rasterizingState.setDepthBias(_depthBiasConstantFactor, + cmdEncoder->_renderingState.setDepthBias(_depthBiasConstantFactor, _depthBiasSlopeFactor, _depthBiasClamp); } +#pragma mark - +#pragma mark MVKCmdSetDepthBiasEnable + +VkResult MVKCmdSetDepthBiasEnable::setContent(MVKCommandBuffer* cmdBuff, + VkBool32 depthBiasEnable) { + _depthBiasEnable = depthBiasEnable; + return VK_SUCCESS; +} + +void MVKCmdSetDepthBiasEnable::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_renderingState.setDepthBiasEnable(_depthBiasEnable); +} + + #pragma mark - #pragma mark MVKCmdSetBlendConstants @@ -361,10 +348,42 @@ VkResult MVKCmdSetBlendConstants::setContent(MVKCommandBuffer* cmdBuff, } void MVKCmdSetBlendConstants::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->_rasterizingState.setBlendConstants(_blendConstants, true); + cmdEncoder->_renderingState.setBlendConstants(_blendConstants, true); } +#pragma mark - +#pragma mark MVKCmdSetLogicOp + +VkResult MVKCmdSetLogicOp::setContent(MVKCommandBuffer* cmdBuff, + VkLogicOp logicOp) { + // Validate + if (logicOp != VK_LOGIC_OP_COPY) { + return reportError(VK_ERROR_FEATURE_NOT_PRESENT, "Metal does not support blending using logic operations."); + } + + return VK_SUCCESS; +} + +void MVKCmdSetLogicOp::encode(MVKCommandEncoder* cmdEncoder) {} + + +#pragma mark - +#pragma mark MVKCmdSetLogicOpEnable + +VkResult MVKCmdSetLogicOpEnable::setContent(MVKCommandBuffer* cmdBuff, + VkBool32 logicOpEnable) { + // Validate + if (logicOpEnable) { + return reportError(VK_ERROR_FEATURE_NOT_PRESENT, "Metal does not support blending using logic operations."); + } + + return VK_SUCCESS; +} + +void MVKCmdSetLogicOpEnable::encode(MVKCommandEncoder* cmdEncoder) {} + + #pragma mark - #pragma mark MVKCmdSetDepthTestEnable @@ -528,7 +547,7 @@ VkResult MVKCmdSetStencilReference::setContent(MVKCommandBuffer* cmdBuff, } void MVKCmdSetStencilReference::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->_rasterizingState.setStencilReferenceValues(_faceMask, _stencilReference); + cmdEncoder->_renderingState.setStencilReferenceValues(_faceMask, _stencilReference); } @@ -542,7 +561,7 @@ VkResult MVKCmdSetCullMode::setContent(MVKCommandBuffer* cmdBuff, } void MVKCmdSetCullMode::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->_rasterizingState.setCullMode(_cullMode, true); + cmdEncoder->_renderingState.setCullMode(_cullMode, true); } @@ -556,7 +575,21 @@ VkResult MVKCmdSetFrontFace::setContent(MVKCommandBuffer* cmdBuff, } void MVKCmdSetFrontFace::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->_rasterizingState.setFrontFace(_frontFace, true); + cmdEncoder->_renderingState.setFrontFace(_frontFace, true); +} + + +#pragma mark - +#pragma mark MVKCmdSetPatchControlPoints + +VkResult MVKCmdSetPatchControlPoints::setContent(MVKCommandBuffer* cmdBuff, + uint32_t patchControlPoints) { + _patchControlPoints = patchControlPoints; + return VK_SUCCESS; +} + +void MVKCmdSetPatchControlPoints::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_graphicsPipelineState.setPatchControlPoints(_patchControlPoints); } @@ -570,6 +603,39 @@ VkResult MVKCmdSetPrimitiveTopology::setContent(MVKCommandBuffer* cmdBuff, } void MVKCmdSetPrimitiveTopology::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->_rasterizingState.setPrimitiveTopology(_primitiveTopology, true); + cmdEncoder->_renderingState.setPrimitiveTopology(_primitiveTopology, true); } + +#pragma mark - +#pragma mark MVKCmdSetPrimitiveRestartEnable + +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."); + } + + return VK_SUCCESS; +} + +void MVKCmdSetPrimitiveRestartEnable::encode(MVKCommandEncoder* cmdEncoder) {} + + +#pragma mark - +#pragma mark MVKCmdSetRasterizerDiscardEnable + +VkResult MVKCmdSetRasterizerDiscardEnable::setContent(MVKCommandBuffer* cmdBuff, + VkBool32 rasterizerDiscardEnable) { + _rasterizerDiscardEnable = rasterizerDiscardEnable; + return VK_SUCCESS; +} + +void MVKCmdSetRasterizerDiscardEnable::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->_renderingState.setRasterizerDiscardEnable(_rasterizerDiscardEnable, true); +} diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm index 5ae4fee3..124859bd 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm @@ -1507,7 +1507,7 @@ void MVKCmdClearAttachments::encode(MVKCommandEncoder* cmdEncoder) { // Return to the previous rendering state on the next render activity cmdEncoder->_graphicsPipelineState.markDirty(); cmdEncoder->_depthStencilState.markDirty(); - cmdEncoder->_rasterizingState.markDirty(); + cmdEncoder->_renderingState.markDirty(); } template diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h index cc1d7539..94f4585c 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h @@ -432,13 +432,13 @@ public: id _mtlRenderEncoder; /** Tracks the current graphics pipeline bound to the encoder. */ - MVKPipelineCommandEncoderState _graphicsPipelineState; + MVKGraphicsPipelineCommandEncoderState _graphicsPipelineState; /** Tracks the current graphics resources state of the encoder. */ MVKGraphicsResourcesCommandEncoderState _graphicsResourcesState; /** Tracks the current compute pipeline bound to the encoder. */ - MVKPipelineCommandEncoderState _computePipelineState; + MVKComputePipelineCommandEncoderState _computePipelineState; /** Tracks the current compute resources state of the encoder. */ MVKComputeResourcesCommandEncoderState _computeResourcesState; @@ -446,8 +446,8 @@ public: /** Tracks the current depth stencil state of the encoder. */ MVKDepthStencilCommandEncoderState _depthStencilState; - /** Tracks the current rasterizing states of the encoder. */ - MVKRasterizingCommandEncoderState _rasterizingState; + /** Tracks the current rendering states of the encoder. */ + MVKRenderingCommandEncoderState _renderingState; /** The size of the threadgroup for the compute shader. */ MTLSize _mtlThreadgroupSize; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index d640730c..55127489 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -25,7 +25,7 @@ #include "MVKFoundation.h" #include "MTLRenderPassDescriptor+MoltenVK.h" #include "MVKCmdDraw.h" -#include "MVKCmdRenderPass.h" +#include "MVKCmdRendering.h" #include using namespace std; @@ -608,7 +608,7 @@ void MVKCommandEncoder::beginMetalRenderPass(MVKCommandUse cmdUse) { _graphicsPipelineState.beginMetalRenderPass(); _graphicsResourcesState.beginMetalRenderPass(); _depthStencilState.beginMetalRenderPass(); - _rasterizingState.beginMetalRenderPass(); + _renderingState.beginMetalRenderPass(); _vertexPushConstants.beginMetalRenderPass(); _tessCtlPushConstants.beginMetalRenderPass(); _tessEvalPushConstants.beginMetalRenderPass(); @@ -729,7 +729,7 @@ void MVKCommandEncoder::finalizeDrawState(MVKGraphicsStage stage) { _graphicsPipelineState.encode(stage); // Must do first..it sets others _graphicsResourcesState.encode(stage); // Before push constants, to allow them to override. _depthStencilState.encode(stage); - _rasterizingState.encode(stage); + _renderingState.encode(stage); _vertexPushConstants.encode(stage); _tessCtlPushConstants.encode(stage); _tessEvalPushConstants.encode(stage); @@ -823,7 +823,7 @@ void MVKCommandEncoder::endMetalRenderEncoding() { _graphicsPipelineState.endMetalRenderPass(); _graphicsResourcesState.endMetalRenderPass(); _depthStencilState.endMetalRenderPass(); - _rasterizingState.endMetalRenderPass(); + _renderingState.endMetalRenderPass(); _vertexPushConstants.endMetalRenderPass(); _tessCtlPushConstants.endMetalRenderPass(); _tessEvalPushConstants.endMetalRenderPass(); @@ -1124,7 +1124,7 @@ MVKCommandEncoder::MVKCommandEncoder(MVKCommandBuffer* cmdBuffer, _computePipelineState(this), _computeResourcesState(this), _depthStencilState(this), - _rasterizingState(this), + _renderingState(this), _vertexPushConstants(this, VK_SHADER_STAGE_VERTEX_BIT), _tessCtlPushConstants(this, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT), _tessEvalPushConstants(this, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT), diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h index c8919538..c518c54a 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h @@ -119,20 +119,15 @@ protected: #pragma mark - #pragma mark MVKPipelineCommandEncoderState -/** Holds encoder state established by pipeline commands. */ +/** Abstract class to hold encoder state established by pipeline commands. */ class MVKPipelineCommandEncoderState : public MVKCommandEncoderState { public: + virtual void bindPipeline(MVKPipeline* pipeline); - /** Binds the pipeline. */ - void bindPipeline(MVKPipeline* pipeline); - - /** Returns the currently bound pipeline. */ MVKPipeline* getPipeline(); - /** Constructs this instance for the specified command encoder. */ - MVKPipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder) - : MVKCommandEncoderState(cmdEncoder) {} + MVKPipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} protected: void encodeImpl(uint32_t stage) override; @@ -141,6 +136,42 @@ protected: }; +#pragma mark - +#pragma mark MVKGraphicsPipelineCommandEncoderState + +/** Holds encoder state established by graphics pipeline commands. */ +class MVKGraphicsPipelineCommandEncoderState : public MVKPipelineCommandEncoderState { + +public: + void bindPipeline(MVKPipeline* pipeline) override; + + MVKGraphicsPipeline* getGraphicsPipeline() { return (MVKGraphicsPipeline*)getPipeline(); } + + void setPatchControlPoints(uint32_t patchControlPoints); + uint32_t getPatchControlPoints(); + + MVKGraphicsPipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKPipelineCommandEncoderState(cmdEncoder) {} + +protected: + uint32_t _patchControlPoints[StateScope::Count] = {}; +}; + + +#pragma mark - +#pragma mark MVKComputePipelineCommandEncoderState + +/** Holds encoder state established by compute pipeline commands. */ +class MVKComputePipelineCommandEncoderState : public MVKPipelineCommandEncoderState { + +public: + MVKComputePipeline* getComputePipeline() { return (MVKComputePipeline*)getPipeline(); } + + MVKComputePipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKPipelineCommandEncoderState(cmdEncoder) {} + +protected: +}; + + #pragma mark - #pragma mark MVKPushConstantsCommandEncoderState @@ -233,7 +264,7 @@ protected: #pragma mark - -#pragma mark MVKRasterizingCommandEncoderState +#pragma mark MVKRenderingCommandEncoderState struct MVKDepthBias { float depthBiasConstantFactor; @@ -256,8 +287,8 @@ struct MVKMTLScissors { uint32_t scissorCount; }; -/** Holds encoder state established by various state commands. */ -class MVKRasterizingCommandEncoderState : public MVKCommandEncoderState { +/** Holds encoder state established by various rendering state commands. */ +class MVKRenderingCommandEncoderState : public MVKCommandEncoderState { public: void setCullMode(VkCullModeFlags cullMode, bool isDynamic); @@ -281,9 +312,11 @@ public: void setViewports(const MVKArrayRef viewports, uint32_t firstViewport, bool isDynamic); void setScissors(const MVKArrayRef scissors, uint32_t firstScissor, bool isDynamic); + void setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable, bool isDynamic); + void beginMetalRenderPass() override; - MVKRasterizingCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} + MVKRenderingCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {} protected: void encodeImpl(uint32_t stage) override; @@ -312,6 +345,7 @@ protected: MVKRenderStateFlags _dirtyStates; MVKRenderStateFlags _modifiedStates; bool _mtlDepthBiasEnable[StateScope::Count] = {}; + bool _mtlRasterizerDiscardEnable[StateScope::Count] = {}; bool _cullBothFaces[StateScope::Count] = {}; }; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm index 828d7c09..72db24d6 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm @@ -36,7 +36,7 @@ MVKVulkanAPIObject* MVKCommandEncoderState::getVulkanAPIObject() { return _cmdEn MVKDevice* MVKCommandEncoderState::getDevice() { return _cmdEncoder->getDevice(); } bool MVKCommandEncoderState::isDynamicState(MVKRenderStateType state) { - auto* gpl = (MVKGraphicsPipeline*)_cmdEncoder->_graphicsPipelineState.getPipeline(); + auto* gpl = _cmdEncoder->_graphicsPipelineState.getGraphicsPipeline(); return !gpl || gpl->isDynamicState(state); } @@ -59,6 +59,23 @@ void MVKPipelineCommandEncoderState::encodeImpl(uint32_t stage) { } +#pragma mark - +#pragma mark MVKGraphicsPipelineCommandEncoderState + +void MVKGraphicsPipelineCommandEncoderState::bindPipeline(MVKPipeline* pipeline) { + MVKPipelineCommandEncoderState::bindPipeline(pipeline); + _patchControlPoints[StateScope::Static] = getGraphicsPipeline()->_tessInfo.patchControlPoints; +} + +void MVKGraphicsPipelineCommandEncoderState::setPatchControlPoints(uint32_t patchControlPoints) { + _patchControlPoints[StateScope::Dynamic] = patchControlPoints; +} + +uint32_t MVKGraphicsPipelineCommandEncoderState::getPatchControlPoints() { + return getContent(_patchControlPoints, PatchControlPoints); +} + + #pragma mark - #pragma mark MVKPushConstantsCommandEncoderState @@ -147,7 +164,7 @@ void MVKPushConstantsCommandEncoderState::encodeImpl(uint32_t stage) { } bool MVKPushConstantsCommandEncoderState::isTessellating() { - MVKGraphicsPipeline* gp = (MVKGraphicsPipeline*)_cmdEncoder->_graphicsPipelineState.getPipeline(); + auto* gp = _cmdEncoder->_graphicsPipelineState.getGraphicsPipeline(); return gp ? gp->isTessellationPipeline() : false; } @@ -291,32 +308,32 @@ void MVKDepthStencilCommandEncoderState::encodeImpl(uint32_t stage) { #pragma mark - -#pragma mark MVKRasterizingCommandEncoderState +#pragma mark MVKRenderingCommandEncoderState #define getContent(state) getContent(_mtl##state, state) #define setContent(state) setContent(_mtl##state, &mtl##state, state, isDynamic) -void MVKRasterizingCommandEncoderState::setCullMode(VkCullModeFlags cullMode, bool isDynamic) { +void MVKRenderingCommandEncoderState::setCullMode(VkCullModeFlags cullMode, bool isDynamic) { auto mtlCullMode = mvkMTLCullModeFromVkCullModeFlags(cullMode); setContent(CullMode); _cullBothFaces[isDynamic ? StateScope::Dynamic : StateScope::Static] = (cullMode == VK_CULL_MODE_FRONT_AND_BACK); } -void MVKRasterizingCommandEncoderState::setFrontFace(VkFrontFace frontFace, bool isDynamic) { +void MVKRenderingCommandEncoderState::setFrontFace(VkFrontFace frontFace, bool isDynamic) { auto mtlFrontFace = mvkMTLWindingFromVkFrontFace(frontFace); setContent(FrontFace); } -void MVKRasterizingCommandEncoderState::setPrimitiveTopology(VkPrimitiveTopology topology, bool isDynamic) { +void MVKRenderingCommandEncoderState::setPrimitiveTopology(VkPrimitiveTopology topology, bool isDynamic) { auto mtlPrimitiveTopology = mvkMTLPrimitiveTypeFromVkPrimitiveTopology(topology); setContent(PrimitiveTopology); } -MTLPrimitiveType MVKRasterizingCommandEncoderState::getPrimitiveType() { +MTLPrimitiveType MVKRenderingCommandEncoderState::getPrimitiveType() { return getContent(PrimitiveTopology); } -bool MVKRasterizingCommandEncoderState::isDrawingTriangles() { +bool MVKRenderingCommandEncoderState::isDrawingTriangles() { switch (getPrimitiveType()) { case MTLPrimitiveTypeTriangle: return true; case MTLPrimitiveTypeTriangleStrip: return true; @@ -324,18 +341,18 @@ bool MVKRasterizingCommandEncoderState::isDrawingTriangles() { } } -void MVKRasterizingCommandEncoderState::setPolygonMode(VkPolygonMode polygonMode, bool isDynamic) { +void MVKRenderingCommandEncoderState::setPolygonMode(VkPolygonMode polygonMode, bool isDynamic) { auto mtlPolygonMode = mvkMTLTriangleFillModeFromVkPolygonMode(polygonMode); setContent(PolygonMode); } -void MVKRasterizingCommandEncoderState::setBlendConstants(float blendConstants[4], bool isDynamic) { +void MVKRenderingCommandEncoderState::setBlendConstants(float blendConstants[4], bool isDynamic) { MVKColor32 mtlBlendConstants; mvkCopy(mtlBlendConstants.float32, blendConstants, 4); setContent(BlendConstants); } -void MVKRasterizingCommandEncoderState::setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo) { +void MVKRenderingCommandEncoderState::setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo) { bool isDynamic = false; bool mtlDepthBiasEnable = static_cast(vkRasterInfo.depthBiasEnable); @@ -349,7 +366,7 @@ void MVKRasterizingCommandEncoderState::setDepthBias(const VkPipelineRasterizati setContent(DepthBias); } -void MVKRasterizingCommandEncoderState::setDepthBias(float depthBiasConstantFactor, +void MVKRenderingCommandEncoderState::setDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor, float depthBiasClamp) { bool isDynamic = true; @@ -361,18 +378,18 @@ void MVKRasterizingCommandEncoderState::setDepthBias(float depthBiasConstantFact setContent(DepthBias); } -void MVKRasterizingCommandEncoderState::setDepthBiasEnable(VkBool32 depthBiasEnable) { +void MVKRenderingCommandEncoderState::setDepthBiasEnable(VkBool32 depthBiasEnable) { bool isDynamic = true; bool mtlDepthBiasEnable = static_cast(depthBiasEnable); setContent(DepthBiasEnable); } -void MVKRasterizingCommandEncoderState::setDepthClipEnable(bool depthClip, bool isDynamic) { +void MVKRenderingCommandEncoderState::setDepthClipEnable(bool depthClip, bool isDynamic) { auto mtlDepthClipEnable = depthClip ? MTLDepthClipModeClip : MTLDepthClipModeClamp; setContent(DepthClipEnable); } -void MVKRasterizingCommandEncoderState::setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) { +void MVKRenderingCommandEncoderState::setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) { bool isDynamic = false; MVKStencilReference mtlStencilReference = { .frontFaceValue = vkDepthStencilInfo.front.reference, @@ -381,7 +398,7 @@ void MVKRasterizingCommandEncoderState::setStencilReferenceValues(const VkPipeli setContent(StencilReference); } -void MVKRasterizingCommandEncoderState::setStencilReferenceValues(VkStencilFaceFlags faceMask, uint32_t stencilReference) { +void MVKRenderingCommandEncoderState::setStencilReferenceValues(VkStencilFaceFlags faceMask, uint32_t stencilReference) { bool isDynamic = true; MVKStencilReference mtlStencilReference = _mtlStencilReference[StateScope::Dynamic]; if (shouldUpdateFace(FRONT)) { mtlStencilReference.frontFaceValue = stencilReference; } @@ -389,7 +406,7 @@ void MVKRasterizingCommandEncoderState::setStencilReferenceValues(VkStencilFaceF setContent(StencilReference); } -void MVKRasterizingCommandEncoderState::setViewports(const MVKArrayRef viewports, +void MVKRenderingCommandEncoderState::setViewports(const MVKArrayRef viewports, uint32_t firstViewport, bool isDynamic) { uint32_t maxViewports = getDevice()->_pProperties->limits.maxViewports; @@ -404,7 +421,7 @@ void MVKRasterizingCommandEncoderState::setViewports(const MVKArrayRef scissors, +void MVKRenderingCommandEncoderState::setScissors(const MVKArrayRef scissors, uint32_t firstScissor, bool isDynamic) { uint32_t maxScissors = getDevice()->_pProperties->limits.maxViewports; @@ -419,7 +436,14 @@ void MVKRasterizingCommandEncoderState::setScissors(const MVKArrayRef setContent(Scissors); } -void MVKRasterizingCommandEncoderState::encodeImpl(uint32_t stage) { +void MVKRenderingCommandEncoderState::setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable, bool isDynamic) { + bool mtlRasterizerDiscardEnable = static_cast(rasterizerDiscardEnable); + setContent(RasterizerDiscardEnable); +} + +#pragma mark Encoding + +void MVKRenderingCommandEncoderState::encodeImpl(uint32_t stage) { if (stage != kMVKGraphicsStageRasterization) { return; } auto& rendEnc = _cmdEncoder->_mtlRenderEncoder; @@ -460,14 +484,15 @@ void MVKRasterizingCommandEncoderState::encodeImpl(uint32_t stage) { } } + // If rasterizing discard has been dynamically enabled, or culling has been dynamically + // set to front-and-back, emulate this by using zeroed scissor rectangles. if (isDirty(Scissors)) { - auto mtlScissors = getContent(Scissors); - - // If culling has been dynamically set to front-and-back, emulate this by using zeroed scissor rectangles. static MTLScissorRect zeroRect = {}; - bool cullBothFaces = isDrawingTriangles() && _cullBothFaces[StateScope::Dynamic] && isDynamicState(CullMode); + auto mtlScissors = getContent(Scissors); + bool shouldDiscard = ((_mtlRasterizerDiscardEnable[StateScope::Dynamic] && isDynamicState(RasterizerDiscardEnable)) || + (isDrawingTriangles() && _cullBothFaces[StateScope::Dynamic] && isDynamicState(CullMode))); for (uint32_t sIdx = 0; sIdx < mtlScissors.scissorCount; sIdx++) { - mtlScissors.scissors[sIdx] = cullBothFaces ? zeroRect : _cmdEncoder->clipToRenderArea(mtlScissors.scissors[sIdx]); + mtlScissors.scissors[sIdx] = shouldDiscard ? zeroRect : _cmdEncoder->clipToRenderArea(mtlScissors.scissors[sIdx]); } if (_cmdEncoder->_pDeviceFeatures->multiViewport) { @@ -481,13 +506,13 @@ void MVKRasterizingCommandEncoderState::encodeImpl(uint32_t stage) { } // Return whether state is dirty, and mark it not dirty -bool MVKRasterizingCommandEncoderState::isDirty(MVKRenderStateType state) { +bool MVKRenderingCommandEncoderState::isDirty(MVKRenderStateType state) { bool rslt = _dirtyStates.isEnabled(state); _dirtyStates.disable(state); return rslt; } -void MVKRasterizingCommandEncoderState::beginMetalRenderPass() { +void MVKRenderingCommandEncoderState::beginMetalRenderPass() { MVKCommandEncoderState::beginMetalRenderPass(); _dirtyStates = _modifiedStates; } @@ -803,7 +828,7 @@ void MVKGraphicsResourcesCommandEncoderState::markDirty() { void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) { - MVKGraphicsPipeline* pipeline = (MVKGraphicsPipeline*)getPipeline(); + auto* pipeline = _cmdEncoder->_graphicsPipelineState.getGraphicsPipeline(); bool fullImageViewSwizzle = pipeline->fullImageViewSwizzle() || getDevice()->_pMetalFeatures->nativeTextureSwizzle; bool forTessellation = pipeline->isTessellationPipeline(); bool isDynamicVertexStride = pipeline->isDynamicState(VertexStride); diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandPool.h b/MoltenVK/MoltenVK/Commands/MVKCommandPool.h index a6b1a38b..e2325857 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandPool.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandPool.h @@ -23,7 +23,7 @@ #include "MVKCommandEncodingPool.h" #include "MVKCommand.h" #include "MVKCmdPipeline.h" -#include "MVKCmdRenderPass.h" +#include "MVKCmdRendering.h" #include "MVKCmdDispatch.h" #include "MVKCmdDraw.h" #include "MVKCmdTransfer.h" diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index 3035677f..880f5551 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -87,8 +87,11 @@ MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(BindDescriptorSetsDynamic, 4) MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(SetViewport, 1) MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(SetScissor, 1) MVK_CMD_TYPE_POOL(SetLineWidth) -MVK_CMD_TYPE_POOL(SetDepthBias) MVK_CMD_TYPE_POOL(SetBlendConstants) +MVK_CMD_TYPE_POOL(SetLogicOp) +MVK_CMD_TYPE_POOL(SetLogicOpEnable) +MVK_CMD_TYPE_POOL(SetDepthBias) +MVK_CMD_TYPE_POOL(SetDepthBiasEnable) MVK_CMD_TYPE_POOL(SetDepthTestEnable) MVK_CMD_TYPE_POOL(SetDepthWriteEnable) MVK_CMD_TYPE_POOL(SetDepthCompareOp) @@ -102,6 +105,9 @@ MVK_CMD_TYPE_POOL(SetStencilReference) MVK_CMD_TYPE_POOL(SetCullMode) MVK_CMD_TYPE_POOL(SetFrontFace) MVK_CMD_TYPE_POOL(SetPrimitiveTopology) +MVK_CMD_TYPE_POOL(SetPatchControlPoints) +MVK_CMD_TYPE_POOL(SetPrimitiveRestartEnable) +MVK_CMD_TYPE_POOL(SetRasterizerDiscardEnable) MVK_CMD_TYPE_POOLS_FROM_2_THRESHOLDS(BindVertexBuffers, 1, 2) MVK_CMD_TYPE_POOL(BindIndexBuffer) MVK_CMD_TYPE_POOL(Draw) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index c2fe1e86..a660be0a 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -392,6 +392,13 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) { extDynState->extendedDynamicState = true; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: { + auto* extDynState2 = (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT*)next; + extDynState2->extendedDynamicState2 = true; + extDynState2->extendedDynamicState2LogicOp = false; + extDynState2->extendedDynamicState2PatchControlPoints = true; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: { auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next; interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def index 4e9f3bed..b9792833 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def @@ -65,6 +65,7 @@ MVK_DEVICE_FEATURE_EXTN(FragmentShaderBarycentric, FRAGMENT_SHADER_BARYCENTRI MVK_DEVICE_FEATURE_EXTN(PortabilitySubset, PORTABILITY_SUBSET, KHR, 15) MVK_DEVICE_FEATURE_EXTN(4444Formats, 4444_FORMATS, EXT, 2) MVK_DEVICE_FEATURE_EXTN(ExtendedDynamicState, EXTENDED_DYNAMIC_STATE, EXT, 1) +MVK_DEVICE_FEATURE_EXTN(ExtendedDynamicState2, EXTENDED_DYNAMIC_STATE_2, EXT, 3) MVK_DEVICE_FEATURE_EXTN(FragmentShaderInterlock, FRAGMENT_SHADER_INTERLOCK, EXT, 3) MVK_DEVICE_FEATURE_EXTN(PipelineCreationCacheControl, PIPELINE_CREATION_CACHE_CONTROL, EXT, 1) MVK_DEVICE_FEATURE_EXTN(Robustness2, ROBUSTNESS_2, EXT, 3) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index acf6670f..b08f6741 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -698,6 +698,9 @@ void MVKInstance::initProcAddrs() { ADD_DVC_EXT_ENTRY_POINT(vkReleaseSwapchainImagesEXT, EXT_SWAPCHAIN_MAINTENANCE_1); ADD_DVC_EXT_ENTRY_POINT(vkGetRefreshCycleDurationGOOGLE, GOOGLE_DISPLAY_TIMING); ADD_DVC_EXT_ENTRY_POINT(vkGetPastPresentationTimingGOOGLE, GOOGLE_DISPLAY_TIMING); + ADD_DVC_EXT_ENTRY_POINT(vkCmdSetLogicOpEXT, EXT_EXTENDED_DYNAMIC_STATE_2); + ADD_DVC_EXT_ENTRY_POINT(vkCmdSetPatchControlPointsEXT, EXT_EXTENDED_DYNAMIC_STATE_2); + ADD_DVC_EXT_ENTRY_POINT(vkCmdSetLogicOpEnableEXT, EXT_EXTENDED_DYNAMIC_STATE_3); } void MVKInstance::logVersions() { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h index c7f67db1..68e10dd8 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.h @@ -232,8 +232,13 @@ enum MVKRenderStateType { DepthTestEnable, DepthWriteEnable, FrontFace, + LogicOp, + LogicOpEnable, + PatchControlPoints, PolygonMode, + PrimitiveRestartEnable, PrimitiveTopology, + RasterizerDiscardEnable, SampleLocations, Scissors, StencilCompareMask, @@ -273,9 +278,6 @@ public: /** Returns whether this pipeline has tessellation shaders. */ bool isTessellationPipeline() { return _tessInfo.patchControlPoints > 0; } - /** Returns the number of input tessellation patch control points. */ - uint32_t getInputControlPointCount() { return _tessInfo.patchControlPoints; } - /** Returns the number of output tessellation patch control points. */ uint32_t getOutputControlPointCount() { return _outputControlPointCount; } @@ -351,6 +353,8 @@ public: ~MVKGraphicsPipeline() override; protected: + friend class MVKGraphicsPipelineCommandEncoderState; + typedef MVKSmallVector SPIRVShaderOutputs; typedef MVKSmallVector SPIRVShaderInputs; @@ -414,10 +418,10 @@ protected: id _mtlPipelineState = nil; float _blendConstants[4] = {}; - VkPrimitiveTopology _vkPrimitiveTopology; MVKShaderImplicitRezBinding _reservedVertexAttributeBufferCount; MVKShaderImplicitRezBinding _viewRangeBufferIndex; MVKShaderImplicitRezBinding _outputBufferIndex; + VkPrimitiveTopology _vkPrimitiveTopology; uint32_t _outputControlPointCount; uint32_t _tessCtlPatchOutputBufferIndex = 0; uint32_t _tessCtlLevelBufferIndex = 0; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm index f41077c8..e361f1ea 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKPipeline.mm @@ -294,17 +294,17 @@ void MVKGraphicsPipeline::encode(MVKCommandEncoder* cmdEncoder, uint32_t stage) cmdEncoder->_depthStencilState.setDepthStencilState(_depthStencilInfo); // Rasterization - cmdEncoder->_rasterizingState.setPrimitiveTopology(_vkPrimitiveTopology, false); - cmdEncoder->_rasterizingState.setBlendConstants(_blendConstants, false); - cmdEncoder->_rasterizingState.setStencilReferenceValues(_depthStencilInfo); - cmdEncoder->_rasterizingState.setViewports(_viewports.contents(), 0, false); - cmdEncoder->_rasterizingState.setScissors(_scissors.contents(), 0, false); + cmdEncoder->_renderingState.setPrimitiveTopology(_vkPrimitiveTopology, false); + cmdEncoder->_renderingState.setBlendConstants(_blendConstants, false); + cmdEncoder->_renderingState.setStencilReferenceValues(_depthStencilInfo); + cmdEncoder->_renderingState.setViewports(_viewports.contents(), 0, false); + cmdEncoder->_renderingState.setScissors(_scissors.contents(), 0, false); if (_hasRasterInfo) { - cmdEncoder->_rasterizingState.setCullMode(_rasterInfo.cullMode, false); - cmdEncoder->_rasterizingState.setFrontFace(_rasterInfo.frontFace, false); - cmdEncoder->_rasterizingState.setPolygonMode(_rasterInfo.polygonMode, false); - cmdEncoder->_rasterizingState.setDepthBias(_rasterInfo); - cmdEncoder->_rasterizingState.setDepthClipEnable( !_rasterInfo.depthClampEnable, false ); + cmdEncoder->_renderingState.setCullMode(_rasterInfo.cullMode, false); + cmdEncoder->_renderingState.setFrontFace(_rasterInfo.frontFace, false); + cmdEncoder->_renderingState.setPolygonMode(_rasterInfo.polygonMode, false); + cmdEncoder->_renderingState.setDepthBias(_rasterInfo); + cmdEncoder->_renderingState.setDepthClipEnable( !_rasterInfo.depthClampEnable, false ); } break; } @@ -497,8 +497,13 @@ MVKGraphicsPipeline::MVKGraphicsPipeline(MVKDevice* device, // Blending - must ignore allowed bad pColorBlendState pointer if rasterization disabled or no color attachments if (_isRasterizingColor && pCreateInfo->pColorBlendState) { mvkCopy(_blendConstants, pCreateInfo->pColorBlendState->blendConstants, 4); + + // Metal does not support blending with logic operations. + if (pCreateInfo->pColorBlendState->logicOpEnable && pCreateInfo->pColorBlendState->logicOp != VK_LOGIC_OP_COPY) { + setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "Metal does not support blending using logic operations.")); + } } else { - float defaultBlendConstants[4] = { 0, 0.0, 0.0, 1.0 }; + static float defaultBlendConstants[4] = { 0, 0.0, 0.0, 1.0 }; mvkCopy(_blendConstants, defaultBlendConstants, 4); } @@ -507,6 +512,14 @@ MVKGraphicsPipeline::MVKGraphicsPipeline(MVKDevice* device, ? 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."); + } + // Rasterization _hasRasterInfo = mvkSetOrClear(&_rasterInfo, pCreateInfo->pRasterizationState); if (_hasRasterInfo) { @@ -548,6 +561,7 @@ static MVKRenderStateType getRenderStateType(VkDynamicState vkDynamicState) { case VK_DYNAMIC_STATE_BLEND_CONSTANTS: return BlendConstants; case VK_DYNAMIC_STATE_CULL_MODE: return CullMode; case VK_DYNAMIC_STATE_DEPTH_BIAS: return DepthBias; + case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE: return DepthBiasEnable; case VK_DYNAMIC_STATE_DEPTH_BOUNDS: return DepthBounds; case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE: return DepthBoundsTestEnable; case VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT: return DepthClipEnable; @@ -556,9 +570,13 @@ 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_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; case VK_DYNAMIC_STATE_POLYGON_MODE_EXT: return PolygonMode; + case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE: return PrimitiveRestartEnable; case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY: return PrimitiveTopology; - case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT: return SampleLocations; + case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE: return RasterizerDiscardEnable; case VK_DYNAMIC_STATE_SCISSOR: return Scissors; case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT: return Scissors; case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: return StencilCompareMask; @@ -579,12 +597,12 @@ void MVKGraphicsPipeline::initDynamicState(const VkGraphicsPipelineCreateInfo* p if ( !pDS ) { return; } for (uint32_t i = 0; i < pDS->dynamicStateCount; i++) { - VkDynamicState vkDynState = pDS->pDynamicStates[i]; + auto dynStateType = getRenderStateType(pDS->pDynamicStates[i]); bool isDynamic = true; // Some dynamic states have other restrictions - switch (vkDynState) { - case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE: + switch (dynStateType) { + case VertexStride: isDynamic = _device->_pMetalFeatures->dynamicVertexStride; if ( !isDynamic ) { setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "This device and platform does not support VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE (macOS 14.0 or iOS/tvOS 17.0, plus either Apple4 or Mac2 GPU).")); } break; @@ -592,7 +610,7 @@ void MVKGraphicsPipeline::initDynamicState(const VkGraphicsPipelineCreateInfo* p break; } - if (isDynamic) { _dynamicState.enable(getRenderStateType(vkDynState)); } + if (isDynamic) { _dynamicState.enable(dynStateType); } } } @@ -1923,10 +1941,10 @@ bool MVKGraphicsPipeline::isRenderingPoints(const VkGraphicsPipelineCreateInfo* (pCreateInfo->pRasterizationState && (pCreateInfo->pRasterizationState->polygonMode == VK_POLYGON_MODE_POINT))); } -// We disable rasterization if either rasterizerDiscard is enabled or the static cull mode dictates it. +// We disable rasterization if either static rasterizerDiscard is enabled or the static cull mode dictates it. bool MVKGraphicsPipeline::isRasterizationDisabled(const VkGraphicsPipelineCreateInfo* pCreateInfo) { return (pCreateInfo->pRasterizationState && - (pCreateInfo->pRasterizationState->rasterizerDiscardEnable || + ((pCreateInfo->pRasterizationState->rasterizerDiscardEnable && !isDynamicState(RasterizerDiscardEnable)) || ((pCreateInfo->pRasterizationState->cullMode == VK_CULL_MODE_FRONT_AND_BACK) && !isDynamicState(CullMode) && pCreateInfo->pInputAssemblyState && (mvkMTLPrimitiveTopologyClassFromVkPrimitiveTopology(pCreateInfo->pInputAssemblyState->topology) == MTLPrimitiveTopologyClassTriangle)))); diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def index 944b81a6..f63ecf98 100644 --- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def +++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def @@ -104,6 +104,7 @@ MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT, MVK_EXTENSION(EXT_debug_utils, EXT_DEBUG_UTILS, INSTANCE, 10.11, 8.0, 1.0) MVK_EXTENSION(EXT_descriptor_indexing, EXT_DESCRIPTOR_INDEXING, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(EXT_extended_dynamic_state, EXT_EXTENDED_DYNAMIC_STATE, DEVICE, 10.11, 8.0, 1.0) +MVK_EXTENSION(EXT_extended_dynamic_state2, EXT_EXTENDED_DYNAMIC_STATE_2, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(EXT_external_memory_host, EXT_EXTERNAL_MEMORY_HOST, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(EXT_fragment_shader_interlock, EXT_FRAGMENT_SHADER_INTERLOCK, DEVICE, 10.13, 11.0, 1.0) MVK_EXTENSION(EXT_hdr_metadata, EXT_HDR_METADATA, DEVICE, 10.15, MVK_NA, MVK_NA) diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index cd6d15bf..642ad040 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2638,7 +2638,14 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetCullMode( MVKTraceVulkanCallEnd(); } -MVK_PUBLIC_VULKAN_STUB(vkCmdSetDepthBiasEnable, void, VkCommandBuffer, VkBool32) +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBiasEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBiasEnable) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(SetDepthBiasEnable, commandBuffer, depthBiasEnable); + MVKTraceVulkanCallEnd(); +} MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBoundsTestEnable( VkCommandBuffer commandBuffer, @@ -2695,7 +2702,14 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetFrontFace( MVKTraceVulkanCallEnd(); } -MVK_PUBLIC_VULKAN_STUB(vkCmdSetPrimitiveRestartEnable, void, VkCommandBuffer, VkBool32) +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetPrimitiveRestartEnable( + VkCommandBuffer commandBuffer, + VkBool32 primitiveRestartEnable) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(SetPrimitiveRestartEnable, commandBuffer, primitiveRestartEnable); + MVKTraceVulkanCallEnd(); +} MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetPrimitiveTopology( VkCommandBuffer commandBuffer, @@ -2706,7 +2720,14 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetPrimitiveTopology( MVKTraceVulkanCallEnd(); } -MVK_PUBLIC_VULKAN_STUB(vkCmdSetRasterizerDiscardEnable, void, VkCommandBuffer, VkBool32) +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetRasterizerDiscardEnable( + VkCommandBuffer commandBuffer, + VkBool32 rasterizerDiscardEnable) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(SetRasterizerDiscardEnable, commandBuffer, rasterizerDiscardEnable); + MVKTraceVulkanCallEnd(); +} MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetScissorWithCount( VkCommandBuffer commandBuffer, @@ -2842,7 +2863,6 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkSetPrivateData( } - #pragma mark - #pragma mark VK_KHR_bind_memory2 extension @@ -3607,6 +3627,45 @@ MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetStencilTestEnable, EXT); MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetViewportWithCount, EXT); +#pragma mark - +#pragma mark VK_EXT_extended_dynamic_state2 +MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetDepthBiasEnable, EXT); + +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetLogicOpEXT( + VkCommandBuffer commandBuffer, + VkLogicOp logicOp) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(SetLogicOp, commandBuffer, logicOp); + MVKTraceVulkanCallEnd(); +} + +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetPatchControlPointsEXT( + VkCommandBuffer commandBuffer, + uint32_t patchControlPoints) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(SetPatchControlPoints, commandBuffer, patchControlPoints); + MVKTraceVulkanCallEnd(); +} + +MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetPrimitiveRestartEnable, EXT); +MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetRasterizerDiscardEnable, EXT); + + +#pragma mark - +#pragma mark VK_EXT_extended_dynamic_state3 + +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetLogicOpEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 logicOpEnable) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(SetLogicOpEnable, commandBuffer, logicOpEnable); + MVKTraceVulkanCallEnd(); +} + + #pragma mark - #pragma mark VK_EXT_external_memory_host extension