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.
This commit is contained in:
Bill Hollings 2023-10-10 12:19:15 -04:00
parent 3c75e114dd
commit f4423428e3
23 changed files with 541 additions and 180 deletions

View File

@ -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`

View File

@ -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()`.

View File

@ -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 = "<group>"; };
A94FB7701C7DFB4800632CA3 /* MVKCmdQueries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdQueries.h; sourceTree = "<group>"; };
A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdQueries.mm; sourceTree = "<group>"; };
A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdRenderPass.h; sourceTree = "<group>"; };
A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdRenderPass.mm; sourceTree = "<group>"; };
A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdRendering.h; sourceTree = "<group>"; };
A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdRendering.mm; sourceTree = "<group>"; };
A94FB7741C7DFB4800632CA3 /* MVKCmdDraw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdDraw.h; sourceTree = "<group>"; };
A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdDraw.mm; sourceTree = "<group>"; };
A94FB7761C7DFB4800632CA3 /* MVKCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCommand.h; sourceTree = "<group>"; };
@ -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 */,

View File

@ -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<MTLComputeCommandEncoder> 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.

View File

@ -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

View File

@ -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 <size_t N>
class MVKCmdExecuteCommands : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
uint32_t commandBuffersCount,
const VkCommandBuffer* pCommandBuffers);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
MVKSmallVector<MVKCommandBuffer*, N> _secondaryCommandBuffers;
};
// Concrete template class implementations.
typedef MVKCmdExecuteCommands<1> MVKCmdExecuteCommands1;
typedef MVKCmdExecuteCommands<16> MVKCmdExecuteCommandsMulti;
#pragma mark -
#pragma mark MVKCmdPipelineBarrier

View File

@ -26,6 +26,33 @@
#include "mvk_datatypes.hpp"
#pragma mark -
#pragma mark MVKCmdExecuteCommands
template <size_t N>
VkResult MVKCmdExecuteCommands<N>::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 <size_t N>
void MVKCmdExecuteCommands<N>::encode(MVKCommandEncoder* cmdEncoder) {
for (auto& cb : _secondaryCommandBuffers) { cmdEncoder->encodeSecondary(cb); }
}
template class MVKCmdExecuteCommands<1>;
template class MVKCmdExecuteCommands<16>;
#pragma mark -
#pragma mark MVKCmdPipelineBarrier

View File

@ -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 <size_t N>
class MVKCmdExecuteCommands : public MVKCommand {
public:
VkResult setContent(MVKCommandBuffer* cmdBuff,
uint32_t commandBuffersCount,
const VkCommandBuffer* pCommandBuffers);
void encode(MVKCommandEncoder* cmdEncoder) override;
protected:
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
MVKSmallVector<MVKCommandBuffer*, N> _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<MVKCommand>* 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<MVKCommand>* 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<MVKCommand>* 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<MVKCommand>* 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<MVKCommand>* 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<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
VkBool32 _rasterizerDiscardEnable;
};

View File

@ -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 <size_t N>
VkResult MVKCmdExecuteCommands<N>::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 <size_t N>
void MVKCmdExecuteCommands<N>::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<N>::setContent(MVKCommandBuffer* cmdBuff,
template <size_t N>
void MVKCmdSetViewport<N>::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<N>::setContent(MVKCommandBuffer* cmdBuff,
template <size_t N>
void MVKCmdSetScissor<N>::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);
}

View File

@ -1507,7 +1507,7 @@ void MVKCmdClearAttachments<N>::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 <size_t N>

View File

@ -432,13 +432,13 @@ public:
id<MTLRenderCommandEncoder> _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;

View File

@ -25,7 +25,7 @@
#include "MVKFoundation.h"
#include "MTLRenderPassDescriptor+MoltenVK.h"
#include "MVKCmdDraw.h"
#include "MVKCmdRenderPass.h"
#include "MVKCmdRendering.h"
#include <sys/mman.h>
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),

View File

@ -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<VkViewport> viewports, uint32_t firstViewport, bool isDynamic);
void setScissors(const MVKArrayRef<VkRect2D> 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] = {};
};

View File

@ -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<bool>(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<bool>(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<VkViewport> viewports,
void MVKRenderingCommandEncoderState::setViewports(const MVKArrayRef<VkViewport> viewports,
uint32_t firstViewport,
bool isDynamic) {
uint32_t maxViewports = getDevice()->_pProperties->limits.maxViewports;
@ -404,7 +421,7 @@ void MVKRasterizingCommandEncoderState::setViewports(const MVKArrayRef<VkViewpor
setContent(Viewports);
}
void MVKRasterizingCommandEncoderState::setScissors(const MVKArrayRef<VkRect2D> scissors,
void MVKRenderingCommandEncoderState::setScissors(const MVKArrayRef<VkRect2D> scissors,
uint32_t firstScissor,
bool isDynamic) {
uint32_t maxScissors = getDevice()->_pProperties->limits.maxViewports;
@ -419,7 +436,14 @@ void MVKRasterizingCommandEncoderState::setScissors(const MVKArrayRef<VkRect2D>
setContent(Scissors);
}
void MVKRasterizingCommandEncoderState::encodeImpl(uint32_t stage) {
void MVKRenderingCommandEncoderState::setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable, bool isDynamic) {
bool mtlRasterizerDiscardEnable = static_cast<bool>(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);

View File

@ -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"

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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() {

View File

@ -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<SPIRVShaderInterfaceVariable, 32> SPIRVShaderOutputs;
typedef MVKSmallVector<SPIRVShaderInterfaceVariable, 32> SPIRVShaderInputs;
@ -414,10 +418,10 @@ protected:
id<MTLRenderPipelineState> _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;

View File

@ -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))));

View File

@ -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)

View File

@ -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