Merge pull request #2036 from billhollings/VK_EXT_extended_dynamic_state
Add support for VK_EXT_extended_dynamic_state & VK_EXT_extended_dynamic_state2 extensions.
This commit is contained in:
commit
61b8712178
@ -312,7 +312,8 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
|
|||||||
- `VK_KHR_16bit_storage`
|
- `VK_KHR_16bit_storage`
|
||||||
- `VK_KHR_8bit_storage`
|
- `VK_KHR_8bit_storage`
|
||||||
- `VK_KHR_bind_memory2`
|
- `VK_KHR_bind_memory2`
|
||||||
- `VK_KHR_buffer_device_address` *(requires GPU Tier 2 argument buffers support)*
|
- `VK_KHR_buffer_device_address`
|
||||||
|
- *Requires GPU Tier 2 argument buffers support.*
|
||||||
- `VK_KHR_copy_commands2`
|
- `VK_KHR_copy_commands2`
|
||||||
- `VK_KHR_create_renderpass2`
|
- `VK_KHR_create_renderpass2`
|
||||||
- `VK_KHR_dedicated_allocation`
|
- `VK_KHR_dedicated_allocation`
|
||||||
@ -322,7 +323,8 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
|
|||||||
- `VK_KHR_device_group_creation`
|
- `VK_KHR_device_group_creation`
|
||||||
- `VK_KHR_driver_properties`
|
- `VK_KHR_driver_properties`
|
||||||
- `VK_KHR_dynamic_rendering`
|
- `VK_KHR_dynamic_rendering`
|
||||||
- `VK_KHR_fragment_shader_barycentric` *(requires Metal 2.2 on Mac or Metal 2.3 on iOS)*
|
- `VK_KHR_fragment_shader_barycentric`
|
||||||
|
- *Requires Metal 2.2 on Mac or Metal 2.3 on iOS.*
|
||||||
- `VK_KHR_get_memory_requirements2`
|
- `VK_KHR_get_memory_requirements2`
|
||||||
- `VK_KHR_get_physical_device_properties2`
|
- `VK_KHR_get_physical_device_properties2`
|
||||||
- `VK_KHR_get_surface_capabilities2`
|
- `VK_KHR_get_surface_capabilities2`
|
||||||
@ -337,14 +339,16 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
|
|||||||
- `VK_KHR_portability_subset`
|
- `VK_KHR_portability_subset`
|
||||||
- `VK_KHR_push_descriptor`
|
- `VK_KHR_push_descriptor`
|
||||||
- `VK_KHR_relaxed_block_layout`
|
- `VK_KHR_relaxed_block_layout`
|
||||||
- `VK_KHR_sampler_mirror_clamp_to_edge` *(requires a Mac GPU or Apple family 7 GPU)*
|
- `VK_KHR_sampler_mirror_clamp_to_edge`
|
||||||
|
- *Requires a Mac GPU or Apple family 7 GPU.*
|
||||||
- `VK_KHR_sampler_ycbcr_conversion`
|
- `VK_KHR_sampler_ycbcr_conversion`
|
||||||
- `VK_KHR_separate_depth_stencil_layouts`
|
- `VK_KHR_separate_depth_stencil_layouts`
|
||||||
- `VK_KHR_shader_draw_parameters`
|
- `VK_KHR_shader_draw_parameters`
|
||||||
- `VK_KHR_shader_float_controls`
|
- `VK_KHR_shader_float_controls`
|
||||||
- `VK_KHR_shader_float16_int8`
|
- `VK_KHR_shader_float16_int8`
|
||||||
- `VK_KHR_shader_non_semantic_info`
|
- `VK_KHR_shader_non_semantic_info`
|
||||||
- `VK_KHR_shader_subgroup_extended_types` *(requires Metal 2.1 on Mac or Metal 2.2 and Apple family 4 on iOS)*
|
- `VK_KHR_shader_subgroup_extended_types`
|
||||||
|
- *Requires Metal 2.1 on Mac or Metal 2.2 and Apple family 4 on iOS.*
|
||||||
- `VK_KHR_spirv_1_4`
|
- `VK_KHR_spirv_1_4`
|
||||||
- `VK_KHR_storage_buffer_storage_class`
|
- `VK_KHR_storage_buffer_storage_class`
|
||||||
- `VK_KHR_surface`
|
- `VK_KHR_surface`
|
||||||
@ -354,53 +358,78 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
|
|||||||
- `VK_KHR_timeline_semaphore`
|
- `VK_KHR_timeline_semaphore`
|
||||||
- `VK_KHR_uniform_buffer_standard_layout`
|
- `VK_KHR_uniform_buffer_standard_layout`
|
||||||
- `VK_KHR_variable_pointers`
|
- `VK_KHR_variable_pointers`
|
||||||
- `VK_EXT_4444_formats` *(requires 16-bit formats and either native texture swizzling or manual swizzling to be enabled)*
|
- `VK_EXT_4444_formats`
|
||||||
- `VK_EXT_buffer_device_address` *(requires GPU Tier 2 argument buffers support)*
|
- *Requires 16-bit formats and either native texture swizzling or manual swizzling to be enabled.*
|
||||||
- `VK_EXT_calibrated_timestamps` *(requires Metal 2.2)*
|
- `VK_EXT_buffer_device_address`
|
||||||
|
- *Requires GPU Tier 2 argument buffers support.*
|
||||||
|
- `VK_EXT_calibrated_timestamps`
|
||||||
|
- *Requires Metal 2.2.*
|
||||||
- `VK_EXT_debug_marker`
|
- `VK_EXT_debug_marker`
|
||||||
- `VK_EXT_debug_report`
|
- `VK_EXT_debug_report`
|
||||||
- `VK_EXT_debug_utils`
|
- `VK_EXT_debug_utils`
|
||||||
- `VK_EXT_descriptor_indexing` *(initial release limited to Metal Tier 1: 96/128 textures,
|
- `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
|
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)*
|
an Intel GPU, and if Metal argument buffers enabled in config.*
|
||||||
|
- `VK_EXT_extended_dynamic_state`
|
||||||
|
- *Requires Metal 3.1 for `VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE`.*
|
||||||
|
- `VK_EXT_extended_dynamic_state2`
|
||||||
|
- *Primitive restart is always enabled, as Metal does not support disabling it (`VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT`).*
|
||||||
- `VK_EXT_external_memory_host`
|
- `VK_EXT_external_memory_host`
|
||||||
- `VK_EXT_fragment_shader_interlock` *(requires Metal 2.0 and Raster Order Groups)*
|
- `VK_EXT_fragment_shader_interlock`
|
||||||
|
- *Requires Metal 2.0 and Raster Order Groups.*
|
||||||
- `VK_EXT_host_query_reset`
|
- `VK_EXT_host_query_reset`
|
||||||
- `VK_EXT_image_robustness`
|
- `VK_EXT_image_robustness`
|
||||||
- `VK_EXT_inline_uniform_block`
|
- `VK_EXT_inline_uniform_block`
|
||||||
- `VK_EXT_memory_budget` *(requires Metal 2.0)*
|
- `VK_EXT_memory_budget`
|
||||||
|
- *Requires Metal 2.0.*
|
||||||
- `VK_EXT_metal_objects`
|
- `VK_EXT_metal_objects`
|
||||||
- `VK_EXT_metal_surface`
|
- `VK_EXT_metal_surface`
|
||||||
- `VK_EXT_pipeline_creation_cache_control`
|
- `VK_EXT_pipeline_creation_cache_control`
|
||||||
- `VK_EXT_pipeline_creation_feedback`
|
- `VK_EXT_pipeline_creation_feedback`
|
||||||
- `VK_EXT_post_depth_coverage` *(iOS and macOS, requires family 4 (A11) or better Apple GPU)*
|
- `VK_EXT_post_depth_coverage`
|
||||||
|
- *iOS and macOS, requires family 4 (A11) or better Apple GPU.*
|
||||||
- `VK_EXT_private_data `
|
- `VK_EXT_private_data `
|
||||||
- `VK_EXT_robustness2`
|
- `VK_EXT_robustness2`
|
||||||
- `VK_EXT_sample_locations`
|
- `VK_EXT_sample_locations`
|
||||||
- `VK_EXT_scalar_block_layout`
|
- `VK_EXT_scalar_block_layout`
|
||||||
- `VK_EXT_separate_stencil_usage`
|
- `VK_EXT_separate_stencil_usage`
|
||||||
- `VK_EXT_shader_atomic_float` *(requires Metal 3.0)*
|
- `VK_EXT_shader_atomic_float`
|
||||||
- `VK_EXT_shader_demote_to_helper_invocation` *(requires Metal Shading Language 2.3)*
|
- *Requires Metal 3.0.*
|
||||||
- `VK_EXT_shader_stencil_export` *(requires Mac GPU family 2 or iOS GPU family 5)*
|
- `VK_EXT_shader_demote_to_helper_invocation`
|
||||||
- `VK_EXT_shader_subgroup_ballot` *(requires Mac GPU family 2 or Apple GPU family 4)*
|
- *Requires Metal Shading Language 2.3.*
|
||||||
- `VK_EXT_shader_subgroup_vote` *(requires Mac GPU family 2 or Apple GPU family 4)*
|
- `VK_EXT_shader_stencil_export`
|
||||||
|
- *Requires Mac GPU family 2 or iOS GPU family 5.*
|
||||||
|
- `VK_EXT_shader_subgroup_ballot`
|
||||||
|
- *Requires Mac GPU family 2 or Apple GPU family 4.*
|
||||||
|
- `VK_EXT_shader_subgroup_vote`
|
||||||
|
- *Requires Mac GPU family 2 or Apple GPU family 4.*
|
||||||
- `VK_EXT_shader_viewport_index_layer`
|
- `VK_EXT_shader_viewport_index_layer`
|
||||||
- `VK_EXT_subgroup_size_control` *(requires Metal 2.1 on Mac or Metal 2.2 and Apple family 4 on iOS)*
|
- `VK_EXT_subgroup_size_control`
|
||||||
|
- *Requires Metal 2.1 on Mac or Metal 2.2 and Apple family 4 on iOS.*
|
||||||
- `VK_EXT_surface_maintenance1`
|
- `VK_EXT_surface_maintenance1`
|
||||||
- `VK_EXT_swapchain_colorspace`
|
- `VK_EXT_swapchain_colorspace`
|
||||||
- `VK_EXT_swapchain_maintenance1`
|
- `VK_EXT_swapchain_maintenance1`
|
||||||
- `VK_EXT_vertex_attribute_divisor`
|
- `VK_EXT_vertex_attribute_divisor`
|
||||||
- `VK_EXT_texel_buffer_alignment` *(requires Metal 2.0)*
|
- `VK_EXT_texel_buffer_alignment`
|
||||||
- `VK_EXT_texture_compression_astc_hdr` *(iOS and macOS, requires family 6 (A13) or better Apple GPU)*
|
- *Requires Metal 2.0.*
|
||||||
- `VK_MVK_ios_surface` *(iOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*
|
- `VK_EXT_texture_compression_astc_hdr`
|
||||||
- `VK_MVK_macos_surface` *(macOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*
|
- *iOS and macOS, requires family 6 (A13) or better Apple GPU.*
|
||||||
|
- `VK_MVK_ios_surface`
|
||||||
|
- *Obsolete. Use `VK_EXT_metal_surface` instead.*
|
||||||
|
- `VK_MVK_macos_surface`
|
||||||
|
- *Obsolete. Use `VK_EXT_metal_surface` instead.*
|
||||||
- `VK_AMD_gpu_shader_half_float`
|
- `VK_AMD_gpu_shader_half_float`
|
||||||
- `VK_AMD_negative_viewport_height`
|
- `VK_AMD_negative_viewport_height`
|
||||||
- `VK_AMD_shader_image_load_store_lod` *(requires Apple GPU)*
|
- `VK_AMD_shader_image_load_store_lod`
|
||||||
- `VK_AMD_shader_trinary_minmax` *(requires Metal 2.1)*
|
- *Requires Apple GPU.*
|
||||||
- `VK_IMG_format_pvrtc` *(requires Apple GPU)*
|
- `VK_AMD_shader_trinary_minmax`
|
||||||
|
- *Requires Metal 2.1.*
|
||||||
|
- `VK_IMG_format_pvrtc`
|
||||||
|
- *Requires Apple GPU.*
|
||||||
- `VK_INTEL_shader_integer_functions2`
|
- `VK_INTEL_shader_integer_functions2`
|
||||||
- `VK_NV_fragment_shader_barycentric` *(requires Metal 2.2 on Mac or Metal 2.3 on iOS)*
|
- `VK_NV_fragment_shader_barycentric`
|
||||||
|
- *Requires Metal 2.2 on Mac or Metal 2.3 on iOS.*
|
||||||
- `VK_NV_glsl_shader`
|
- `VK_NV_glsl_shader`
|
||||||
|
|
||||||
In order to visibly display your content on *macOS*, *iOS*, or *tvOS*, you must enable the
|
In order to visibly display your content on *macOS*, *iOS*, or *tvOS*, you must enable the
|
||||||
@ -623,6 +652,8 @@ Known **MoltenVK** Limitations
|
|||||||
|
|
||||||
This section documents the known limitations in this version of **MoltenVK**.
|
This section documents the known limitations in this version of **MoltenVK**.
|
||||||
|
|
||||||
|
- See [above](#interaction) for known limitations for specific Vulkan extensions.
|
||||||
|
|
||||||
- On *macOS* versions prior to *macOS 10.15.6*, native host-coherent image device memory is not available.
|
- On *macOS* versions prior to *macOS 10.15.6*, native host-coherent image device memory is not available.
|
||||||
Because of this, changes made to `VkImage VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` device memory by the CPU
|
Because of this, changes made to `VkImage VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` device memory by the CPU
|
||||||
or GPU will not be available to the GPU or CPU, respectively, until the memory is flushed or unmapped by
|
or GPU will not be available to the GPU or CPU, respectively, until the memory is flushed or unmapped by
|
||||||
@ -645,4 +676,3 @@ This section documents the known limitations in this version of **MoltenVK**.
|
|||||||
use the *Vulkan Loader and Layers* from the *[Vulkan SDK](https://vulkan.lunarg.com/sdk/home)*.
|
use the *Vulkan Loader and Layers* from the *[Vulkan SDK](https://vulkan.lunarg.com/sdk/home)*.
|
||||||
Refer to the *Vulkan SDK [Getting Started](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html)*
|
Refer to the *Vulkan SDK [Getting Started](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html)*
|
||||||
document for more info.
|
document for more info.
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ Released TBD
|
|||||||
|
|
||||||
- Add support for extensions:
|
- Add support for extensions:
|
||||||
- `VK_KHR_synchronization2`
|
- `VK_KHR_synchronization2`
|
||||||
|
- `VK_EXT_extended_dynamic_state` *(requires Metal 3.1 for `VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE`)*
|
||||||
|
- `VK_EXT_extended_dynamic_state2`
|
||||||
- Fix rare case where vertex attribute buffers are not bound to Metal
|
- Fix rare case where vertex attribute buffers are not bound to Metal
|
||||||
when no other bindings change between pipelines.
|
when no other bindings change between pipelines.
|
||||||
- Ensure objects retained for life of `MTLCommandBuffer` during `vkCmdBlitImage()` & `vkQueuePresentKHR()`.
|
- Ensure objects retained for life of `MTLCommandBuffer` during `vkCmdBlitImage()` & `vkQueuePresentKHR()`.
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
2FEA0A6724902F9F00EEF3AD /* MVKCommonEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */; };
|
2FEA0A6724902F9F00EEF3AD /* MVKCommonEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */; };
|
||||||
2FEA0A6824902F9F00EEF3AD /* MVKWatermark.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149491FB6A3F7005F00B4 /* MVKWatermark.h */; };
|
2FEA0A6824902F9F00EEF3AD /* MVKWatermark.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149491FB6A3F7005F00B4 /* MVKWatermark.h */; };
|
||||||
2FEA0A6924902F9F00EEF3AD /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.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 */; };
|
2FEA0A6B24902F9F00EEF3AD /* MVKCmdPipeline.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB76E1C7DFB4800632CA3 /* MVKCmdPipeline.h */; };
|
||||||
2FEA0A6C24902F9F00EEF3AD /* MVKSmallVectorAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */; };
|
2FEA0A6C24902F9F00EEF3AD /* MVKSmallVectorAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */; };
|
||||||
2FEA0A6D24902F9F00EEF3AD /* MVKPipeline.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB78D1C7DFB4800632CA3 /* MVKPipeline.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 */; };
|
2FEA0A9424902F9F00EEF3AD /* MVKCommandPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB77B1C7DFB4800632CA3 /* MVKCommandPool.mm */; };
|
||||||
2FEA0A9524902F9F00EEF3AD /* MVKCmdDraw.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */; };
|
2FEA0A9524902F9F00EEF3AD /* MVKCmdDraw.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */; };
|
||||||
2FEA0A9624902F9F00EEF3AD /* MVKCommandBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7791C7DFB4800632CA3 /* MVKCommandBuffer.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 */; };
|
2FEA0A9824902F9F00EEF3AD /* MVKBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7801C7DFB4800632CA3 /* MVKBuffer.mm */; };
|
||||||
2FEA0A9924902F9F00EEF3AD /* mvk_datatypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7A91C7DFB4800632CA3 /* mvk_datatypes.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 */; };
|
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 */; };
|
A94FB7C11C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7701C7DFB4800632CA3 /* MVKCmdQueries.h */; };
|
||||||
A94FB7C21C7DFB4800632CA3 /* MVKCmdQueries.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */; };
|
A94FB7C21C7DFB4800632CA3 /* MVKCmdQueries.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */; };
|
||||||
A94FB7C31C7DFB4800632CA3 /* 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 */; };
|
A94FB7C41C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */; };
|
||||||
A94FB7C51C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */; };
|
A94FB7C51C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */; };
|
||||||
A94FB7C61C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */; };
|
A94FB7C61C7DFB4800632CA3 /* MVKCmdRendering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */; };
|
||||||
A94FB7C71C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */; };
|
A94FB7C71C7DFB4800632CA3 /* MVKCmdRendering.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */; };
|
||||||
A94FB7C81C7DFB4800632CA3 /* MVKCmdDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7741C7DFB4800632CA3 /* MVKCmdDraw.h */; };
|
A94FB7C81C7DFB4800632CA3 /* MVKCmdDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7741C7DFB4800632CA3 /* MVKCmdDraw.h */; };
|
||||||
A94FB7C91C7DFB4800632CA3 /* 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 */; };
|
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 */; };
|
DCFD7F0B2A45BC6E007BBBF7 /* MVKCommonEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */; };
|
||||||
DCFD7F0C2A45BC6E007BBBF7 /* MVKWatermark.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149491FB6A3F7005F00B4 /* MVKWatermark.h */; };
|
DCFD7F0C2A45BC6E007BBBF7 /* MVKWatermark.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149491FB6A3F7005F00B4 /* MVKWatermark.h */; };
|
||||||
DCFD7F0D2A45BC6E007BBBF7 /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.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 */; };
|
DCFD7F0F2A45BC6E007BBBF7 /* MVKCmdPipeline.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB76E1C7DFB4800632CA3 /* MVKCmdPipeline.h */; };
|
||||||
DCFD7F102A45BC6E007BBBF7 /* MVKSmallVectorAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */; };
|
DCFD7F102A45BC6E007BBBF7 /* MVKSmallVectorAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */; };
|
||||||
DCFD7F112A45BC6E007BBBF7 /* MVKPipeline.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB78D1C7DFB4800632CA3 /* MVKPipeline.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 */; };
|
DCFD7F3A2A45BC6E007BBBF7 /* MVKCommandPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB77B1C7DFB4800632CA3 /* MVKCommandPool.mm */; };
|
||||||
DCFD7F3B2A45BC6E007BBBF7 /* MVKCmdDraw.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */; };
|
DCFD7F3B2A45BC6E007BBBF7 /* MVKCmdDraw.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7751C7DFB4800632CA3 /* MVKCmdDraw.mm */; };
|
||||||
DCFD7F3C2A45BC6E007BBBF7 /* MVKCommandBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7791C7DFB4800632CA3 /* MVKCommandBuffer.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 */; };
|
DCFD7F3E2A45BC6E007BBBF7 /* MVKBuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7801C7DFB4800632CA3 /* MVKBuffer.mm */; };
|
||||||
DCFD7F3F2A45BC6E007BBBF7 /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; };
|
DCFD7F3F2A45BC6E007BBBF7 /* MVKEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A5E9C525C0822700E9085E /* MVKEnvironment.cpp */; };
|
||||||
DCFD7F402A45BC6E007BBBF7 /* mvk_datatypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7A91C7DFB4800632CA3 /* mvk_datatypes.mm */; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCmdRendering.h; sourceTree = "<group>"; };
|
||||||
A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdRenderPass.mm; 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>"; };
|
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>"; };
|
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>"; };
|
A94FB7761C7DFB4800632CA3 /* MVKCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKCommand.h; sourceTree = "<group>"; };
|
||||||
@ -744,8 +744,8 @@
|
|||||||
A94FB76F1C7DFB4800632CA3 /* MVKCmdPipeline.mm */,
|
A94FB76F1C7DFB4800632CA3 /* MVKCmdPipeline.mm */,
|
||||||
A94FB7701C7DFB4800632CA3 /* MVKCmdQueries.h */,
|
A94FB7701C7DFB4800632CA3 /* MVKCmdQueries.h */,
|
||||||
A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */,
|
A94FB7711C7DFB4800632CA3 /* MVKCmdQueries.mm */,
|
||||||
A94FB7721C7DFB4800632CA3 /* MVKCmdRenderPass.h */,
|
A94FB7721C7DFB4800632CA3 /* MVKCmdRendering.h */,
|
||||||
A94FB7731C7DFB4800632CA3 /* MVKCmdRenderPass.mm */,
|
A94FB7731C7DFB4800632CA3 /* MVKCmdRendering.mm */,
|
||||||
A94FB76C1C7DFB4800632CA3 /* MVKCmdTransfer.h */,
|
A94FB76C1C7DFB4800632CA3 /* MVKCmdTransfer.h */,
|
||||||
A94FB76D1C7DFB4800632CA3 /* MVKCmdTransfer.mm */,
|
A94FB76D1C7DFB4800632CA3 /* MVKCmdTransfer.mm */,
|
||||||
A94FB7761C7DFB4800632CA3 /* MVKCommand.h */,
|
A94FB7761C7DFB4800632CA3 /* MVKCommand.h */,
|
||||||
@ -995,7 +995,7 @@
|
|||||||
2FEA0A6724902F9F00EEF3AD /* MVKCommonEnvironment.h in Headers */,
|
2FEA0A6724902F9F00EEF3AD /* MVKCommonEnvironment.h in Headers */,
|
||||||
2FEA0A6824902F9F00EEF3AD /* MVKWatermark.h in Headers */,
|
2FEA0A6824902F9F00EEF3AD /* MVKWatermark.h in Headers */,
|
||||||
2FEA0A6924902F9F00EEF3AD /* MVKOSExtensions.h in Headers */,
|
2FEA0A6924902F9F00EEF3AD /* MVKOSExtensions.h in Headers */,
|
||||||
2FEA0A6A24902F9F00EEF3AD /* MVKCmdRenderPass.h in Headers */,
|
2FEA0A6A24902F9F00EEF3AD /* MVKCmdRendering.h in Headers */,
|
||||||
2FEA0A6B24902F9F00EEF3AD /* MVKCmdPipeline.h in Headers */,
|
2FEA0A6B24902F9F00EEF3AD /* MVKCmdPipeline.h in Headers */,
|
||||||
2FEA0A6C24902F9F00EEF3AD /* MVKSmallVectorAllocator.h in Headers */,
|
2FEA0A6C24902F9F00EEF3AD /* MVKSmallVectorAllocator.h in Headers */,
|
||||||
2FEA0A6D24902F9F00EEF3AD /* MVKPipeline.h in Headers */,
|
2FEA0A6D24902F9F00EEF3AD /* MVKPipeline.h in Headers */,
|
||||||
@ -1074,7 +1074,7 @@
|
|||||||
A9F042A41FB4CF83009FCCB8 /* MVKCommonEnvironment.h in Headers */,
|
A9F042A41FB4CF83009FCCB8 /* MVKCommonEnvironment.h in Headers */,
|
||||||
A981495D1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */,
|
A981495D1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */,
|
||||||
A9B51BD9225E986A00AC74D2 /* MVKOSExtensions.h in Headers */,
|
A9B51BD9225E986A00AC74D2 /* MVKOSExtensions.h in Headers */,
|
||||||
A94FB7C41C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */,
|
A94FB7C41C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */,
|
||||||
A94FB7BC1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */,
|
A94FB7BC1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */,
|
||||||
A9F3D9DC24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */,
|
A9F3D9DC24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */,
|
||||||
A9C327562AAFBD390025EE79 /* MVKConfigMembers.def in Headers */,
|
A9C327562AAFBD390025EE79 /* MVKConfigMembers.def in Headers */,
|
||||||
@ -1151,7 +1151,7 @@
|
|||||||
A9F042A51FB4CF83009FCCB8 /* MVKCommonEnvironment.h in Headers */,
|
A9F042A51FB4CF83009FCCB8 /* MVKCommonEnvironment.h in Headers */,
|
||||||
A981495E1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */,
|
A981495E1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */,
|
||||||
A9B51BDA225E986A00AC74D2 /* MVKOSExtensions.h in Headers */,
|
A9B51BDA225E986A00AC74D2 /* MVKOSExtensions.h in Headers */,
|
||||||
A94FB7C51C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */,
|
A94FB7C51C7DFB4800632CA3 /* MVKCmdRendering.h in Headers */,
|
||||||
A94FB7BD1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */,
|
A94FB7BD1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */,
|
||||||
A9F3D9DD24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */,
|
A9F3D9DD24732A4D00745190 /* MVKSmallVectorAllocator.h in Headers */,
|
||||||
A94FB7F91C7DFB4800632CA3 /* MVKPipeline.h in Headers */,
|
A94FB7F91C7DFB4800632CA3 /* MVKPipeline.h in Headers */,
|
||||||
@ -1228,7 +1228,7 @@
|
|||||||
DCFD7F0B2A45BC6E007BBBF7 /* MVKCommonEnvironment.h in Headers */,
|
DCFD7F0B2A45BC6E007BBBF7 /* MVKCommonEnvironment.h in Headers */,
|
||||||
DCFD7F0C2A45BC6E007BBBF7 /* MVKWatermark.h in Headers */,
|
DCFD7F0C2A45BC6E007BBBF7 /* MVKWatermark.h in Headers */,
|
||||||
DCFD7F0D2A45BC6E007BBBF7 /* MVKOSExtensions.h in Headers */,
|
DCFD7F0D2A45BC6E007BBBF7 /* MVKOSExtensions.h in Headers */,
|
||||||
DCFD7F0E2A45BC6E007BBBF7 /* MVKCmdRenderPass.h in Headers */,
|
DCFD7F0E2A45BC6E007BBBF7 /* MVKCmdRendering.h in Headers */,
|
||||||
DCFD7F0F2A45BC6E007BBBF7 /* MVKCmdPipeline.h in Headers */,
|
DCFD7F0F2A45BC6E007BBBF7 /* MVKCmdPipeline.h in Headers */,
|
||||||
DCFD7F102A45BC6E007BBBF7 /* MVKSmallVectorAllocator.h in Headers */,
|
DCFD7F102A45BC6E007BBBF7 /* MVKSmallVectorAllocator.h in Headers */,
|
||||||
DCFD7F112A45BC6E007BBBF7 /* MVKPipeline.h in Headers */,
|
DCFD7F112A45BC6E007BBBF7 /* MVKPipeline.h in Headers */,
|
||||||
@ -1674,7 +1674,7 @@
|
|||||||
2FEA0A9424902F9F00EEF3AD /* MVKCommandPool.mm in Sources */,
|
2FEA0A9424902F9F00EEF3AD /* MVKCommandPool.mm in Sources */,
|
||||||
2FEA0A9524902F9F00EEF3AD /* MVKCmdDraw.mm in Sources */,
|
2FEA0A9524902F9F00EEF3AD /* MVKCmdDraw.mm in Sources */,
|
||||||
2FEA0A9624902F9F00EEF3AD /* MVKCommandBuffer.mm in Sources */,
|
2FEA0A9624902F9F00EEF3AD /* MVKCommandBuffer.mm in Sources */,
|
||||||
2FEA0A9724902F9F00EEF3AD /* MVKCmdRenderPass.mm in Sources */,
|
2FEA0A9724902F9F00EEF3AD /* MVKCmdRendering.mm in Sources */,
|
||||||
2FEA0A9824902F9F00EEF3AD /* MVKBuffer.mm in Sources */,
|
2FEA0A9824902F9F00EEF3AD /* MVKBuffer.mm in Sources */,
|
||||||
2FEA0A9924902F9F00EEF3AD /* mvk_datatypes.mm in Sources */,
|
2FEA0A9924902F9F00EEF3AD /* mvk_datatypes.mm in Sources */,
|
||||||
2FEA0A9A24902F9F00EEF3AD /* MVKExtensions.mm in Sources */,
|
2FEA0A9A24902F9F00EEF3AD /* MVKExtensions.mm in Sources */,
|
||||||
@ -1734,7 +1734,7 @@
|
|||||||
A94FB7D61C7DFB4800632CA3 /* MVKCommandPool.mm in Sources */,
|
A94FB7D61C7DFB4800632CA3 /* MVKCommandPool.mm in Sources */,
|
||||||
A94FB7CA1C7DFB4800632CA3 /* MVKCmdDraw.mm in Sources */,
|
A94FB7CA1C7DFB4800632CA3 /* MVKCmdDraw.mm in Sources */,
|
||||||
A94FB7D21C7DFB4800632CA3 /* MVKCommandBuffer.mm in Sources */,
|
A94FB7D21C7DFB4800632CA3 /* MVKCommandBuffer.mm in Sources */,
|
||||||
A94FB7C61C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */,
|
A94FB7C61C7DFB4800632CA3 /* MVKCmdRendering.mm in Sources */,
|
||||||
A94FB7DE1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
|
A94FB7DE1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
|
||||||
A9A5E9C725C0822700E9085E /* MVKEnvironment.cpp in Sources */,
|
A9A5E9C725C0822700E9085E /* MVKEnvironment.cpp in Sources */,
|
||||||
A94FB82A1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */,
|
A94FB82A1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */,
|
||||||
@ -1794,7 +1794,7 @@
|
|||||||
A94FB7D71C7DFB4800632CA3 /* MVKCommandPool.mm in Sources */,
|
A94FB7D71C7DFB4800632CA3 /* MVKCommandPool.mm in Sources */,
|
||||||
A94FB7CB1C7DFB4800632CA3 /* MVKCmdDraw.mm in Sources */,
|
A94FB7CB1C7DFB4800632CA3 /* MVKCmdDraw.mm in Sources */,
|
||||||
A94FB7D31C7DFB4800632CA3 /* MVKCommandBuffer.mm in Sources */,
|
A94FB7D31C7DFB4800632CA3 /* MVKCommandBuffer.mm in Sources */,
|
||||||
A94FB7C71C7DFB4800632CA3 /* MVKCmdRenderPass.mm in Sources */,
|
A94FB7C71C7DFB4800632CA3 /* MVKCmdRendering.mm in Sources */,
|
||||||
A94FB7DF1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
|
A94FB7DF1C7DFB4800632CA3 /* MVKBuffer.mm in Sources */,
|
||||||
A9A5E9C925C0822700E9085E /* MVKEnvironment.cpp in Sources */,
|
A9A5E9C925C0822700E9085E /* MVKEnvironment.cpp in Sources */,
|
||||||
A94FB82B1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */,
|
A94FB82B1C7DFB4800632CA3 /* mvk_datatypes.mm in Sources */,
|
||||||
@ -1854,7 +1854,7 @@
|
|||||||
DCFD7F3A2A45BC6E007BBBF7 /* MVKCommandPool.mm in Sources */,
|
DCFD7F3A2A45BC6E007BBBF7 /* MVKCommandPool.mm in Sources */,
|
||||||
DCFD7F3B2A45BC6E007BBBF7 /* MVKCmdDraw.mm in Sources */,
|
DCFD7F3B2A45BC6E007BBBF7 /* MVKCmdDraw.mm in Sources */,
|
||||||
DCFD7F3C2A45BC6E007BBBF7 /* MVKCommandBuffer.mm in Sources */,
|
DCFD7F3C2A45BC6E007BBBF7 /* MVKCommandBuffer.mm in Sources */,
|
||||||
DCFD7F3D2A45BC6E007BBBF7 /* MVKCmdRenderPass.mm in Sources */,
|
DCFD7F3D2A45BC6E007BBBF7 /* MVKCmdRendering.mm in Sources */,
|
||||||
DCFD7F3E2A45BC6E007BBBF7 /* MVKBuffer.mm in Sources */,
|
DCFD7F3E2A45BC6E007BBBF7 /* MVKBuffer.mm in Sources */,
|
||||||
DCFD7F3F2A45BC6E007BBBF7 /* MVKEnvironment.cpp in Sources */,
|
DCFD7F3F2A45BC6E007BBBF7 /* MVKEnvironment.cpp in Sources */,
|
||||||
DCFD7F402A45BC6E007BBBF7 /* mvk_datatypes.mm in Sources */,
|
DCFD7F402A45BC6E007BBBF7 /* mvk_datatypes.mm in Sources */,
|
||||||
|
@ -383,6 +383,9 @@ MTLViewport mvkMTLViewportFromVkViewport(VkViewport vkViewport);
|
|||||||
/** Returns the Metal MTLScissorRect corresponding to the specified Vulkan VkRect2D. */
|
/** Returns the Metal MTLScissorRect corresponding to the specified Vulkan VkRect2D. */
|
||||||
MTLScissorRect mvkMTLScissorRectFromVkRect2D(VkRect2D vkRect);
|
MTLScissorRect mvkMTLScissorRectFromVkRect2D(VkRect2D vkRect);
|
||||||
|
|
||||||
|
/** Returns the Vulkan VkRect2D corresponding to the specified Metal MTLScissorRect. */
|
||||||
|
VkRect2D mvkVkRect2DFromMTLScissorRect(MTLScissorRect mtlScissorRect);
|
||||||
|
|
||||||
/** Returns the Metal MTLCompareFunction corresponding to the specified Vulkan VkCompareOp, */
|
/** Returns the Metal MTLCompareFunction corresponding to the specified Vulkan VkCompareOp, */
|
||||||
MTLCompareFunction mvkMTLCompareFunctionFromVkCompareOp(VkCompareOp vkOp);
|
MTLCompareFunction mvkMTLCompareFunctionFromVkCompareOp(VkCompareOp vkOp);
|
||||||
|
|
||||||
|
@ -151,6 +151,7 @@ typedef struct {
|
|||||||
MTLArgumentBuffersTier argumentBuffersTier; /**< The argument buffer tier available on this device, as a Metal enumeration. */
|
MTLArgumentBuffersTier argumentBuffersTier; /**< The argument buffer tier available on this device, as a Metal enumeration. */
|
||||||
VkBool32 needsSampleDrefLodArrayWorkaround; /**< If true, sampling from arrayed depth images with explicit LoD is broken and needs a workaround. */
|
VkBool32 needsSampleDrefLodArrayWorkaround; /**< If true, sampling from arrayed depth images with explicit LoD is broken and needs a workaround. */
|
||||||
VkDeviceSize hostMemoryPageSize; /**< The size of a page of host memory on this platform. */
|
VkDeviceSize hostMemoryPageSize; /**< The size of a page of host memory on this platform. */
|
||||||
|
VkBool32 dynamicVertexStride; /**< If true, VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE is supported. */
|
||||||
} MVKPhysicalDeviceMetalFeatures;
|
} MVKPhysicalDeviceMetalFeatures;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,7 +46,7 @@ void MVKCmdDispatch::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
MTLRegion mtlThreadgroupCount = MTLRegionMake3D(_baseGroupX, _baseGroupY, _baseGroupZ, _groupCountX, _groupCountY, _groupCountZ);
|
MTLRegion mtlThreadgroupCount = MTLRegionMake3D(_baseGroupX, _baseGroupY, _baseGroupZ, _groupCountX, _groupCountY, _groupCountZ);
|
||||||
cmdEncoder->finalizeDispatchState(); // Ensure all updated state has been submitted to Metal
|
cmdEncoder->finalizeDispatchState(); // Ensure all updated state has been submitted to Metal
|
||||||
id<MTLComputeCommandEncoder> mtlEncoder = cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch);
|
id<MTLComputeCommandEncoder> mtlEncoder = cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch);
|
||||||
auto* pipeline = (MVKComputePipeline*)cmdEncoder->_computePipelineState.getPipeline();
|
auto* pipeline = cmdEncoder->_computePipelineState.getComputePipeline();
|
||||||
if (pipeline->allowsDispatchBase()) {
|
if (pipeline->allowsDispatchBase()) {
|
||||||
if ([mtlEncoder respondsToSelector: @selector(setStageInRegion:)]) {
|
if ([mtlEncoder respondsToSelector: @selector(setStageInRegion:)]) {
|
||||||
// We'll use the stage-input region to pass the base along to the shader.
|
// We'll use the stage-input region to pass the base along to the shader.
|
||||||
|
@ -37,10 +37,12 @@ class MVKCmdBindVertexBuffers : public MVKCommand {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
uint32_t startBinding,
|
uint32_t firstBinding,
|
||||||
uint32_t bindingCount,
|
uint32_t bindingCount,
|
||||||
const VkBuffer* pBuffers,
|
const VkBuffer* pBuffers,
|
||||||
const VkDeviceSize* pOffsets);
|
const VkDeviceSize* pOffsets,
|
||||||
|
const VkDeviceSize* pSizes,
|
||||||
|
const VkDeviceSize* pStrides);
|
||||||
|
|
||||||
void encode(MVKCommandEncoder* cmdEncoder) override;
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
|
@ -30,20 +30,23 @@
|
|||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
VkResult MVKCmdBindVertexBuffers<N>::setContent(MVKCommandBuffer* cmdBuff,
|
VkResult MVKCmdBindVertexBuffers<N>::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
uint32_t startBinding,
|
uint32_t firstBinding,
|
||||||
uint32_t bindingCount,
|
uint32_t bindingCount,
|
||||||
const VkBuffer* pBuffers,
|
const VkBuffer* pBuffers,
|
||||||
const VkDeviceSize* pOffsets) {
|
const VkDeviceSize* pOffsets,
|
||||||
|
const VkDeviceSize* pSizes,
|
||||||
|
const VkDeviceSize* pStrides) {
|
||||||
MVKDevice* mvkDvc = cmdBuff->getDevice();
|
MVKDevice* mvkDvc = cmdBuff->getDevice();
|
||||||
_bindings.clear(); // Clear for reuse
|
_bindings.clear(); // Clear for reuse
|
||||||
_bindings.reserve(bindingCount);
|
_bindings.reserve(bindingCount);
|
||||||
MVKMTLBufferBinding b;
|
MVKMTLBufferBinding b;
|
||||||
for (uint32_t bindIdx = 0; bindIdx < bindingCount; bindIdx++) {
|
for (uint32_t bindIdx = 0; bindIdx < bindingCount; bindIdx++) {
|
||||||
MVKBuffer* mvkBuffer = (MVKBuffer*)pBuffers[bindIdx];
|
MVKBuffer* mvkBuffer = (MVKBuffer*)pBuffers[bindIdx];
|
||||||
b.index = mvkDvc->getMetalBufferIndexForVertexAttributeBinding(startBinding + bindIdx);
|
b.index = mvkDvc->getMetalBufferIndexForVertexAttributeBinding(firstBinding + bindIdx);
|
||||||
b.mtlBuffer = mvkBuffer->getMTLBuffer();
|
b.mtlBuffer = mvkBuffer->getMTLBuffer();
|
||||||
b.offset = mvkBuffer->getMTLBufferOffset() + pOffsets[bindIdx];
|
b.offset = mvkBuffer->getMTLBufferOffset() + pOffsets[bindIdx];
|
||||||
|
b.size = pSizes ? (uint32_t)pSizes[bindIdx] : 0;
|
||||||
|
b.stride = pStrides ? (uint32_t)pStrides[bindIdx] : 0;
|
||||||
_bindings.push_back(b);
|
_bindings.push_back(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +149,7 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
return;
|
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.
|
// 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) {
|
if (pipeline->getVkPrimitiveTopology() == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) {
|
||||||
@ -169,7 +172,7 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
} tessParams;
|
} tessParams;
|
||||||
uint32_t outControlPointCount = 0;
|
uint32_t outControlPointCount = 0;
|
||||||
if (pipeline->isTessellationPipeline()) {
|
if (pipeline->isTessellationPipeline()) {
|
||||||
tessParams.inControlPointCount = pipeline->getInputControlPointCount();
|
tessParams.inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints();
|
||||||
outControlPointCount = pipeline->getOutputControlPointCount();
|
outControlPointCount = pipeline->getOutputControlPointCount();
|
||||||
tessParams.patchCount = mvkCeilingDivide(_vertexCount, tessParams.inControlPointCount) * _instanceCount;
|
tessParams.patchCount = mvkCeilingDivide(_vertexCount, tessParams.inControlPointCount) * _instanceCount;
|
||||||
}
|
}
|
||||||
@ -296,13 +299,13 @@ void MVKCmdDraw::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
uint32_t instanceCount = _instanceCount * viewCount;
|
uint32_t instanceCount = _instanceCount * viewCount;
|
||||||
cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _firstInstance);
|
cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _firstInstance);
|
||||||
if (cmdEncoder->_pDeviceMetalFeatures->baseVertexInstanceDrawing) {
|
if (cmdEncoder->_pDeviceMetalFeatures->baseVertexInstanceDrawing) {
|
||||||
[cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_mtlPrimitiveType
|
[cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_renderingState.getPrimitiveType()
|
||||||
vertexStart: _firstVertex
|
vertexStart: _firstVertex
|
||||||
vertexCount: _vertexCount
|
vertexCount: _vertexCount
|
||||||
instanceCount: instanceCount
|
instanceCount: instanceCount
|
||||||
baseInstance: _firstInstance];
|
baseInstance: _firstInstance];
|
||||||
} else {
|
} else {
|
||||||
[cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_mtlPrimitiveType
|
[cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_renderingState.getPrimitiveType()
|
||||||
vertexStart: _firstVertex
|
vertexStart: _firstVertex
|
||||||
vertexCount: _vertexCount
|
vertexCount: _vertexCount
|
||||||
instanceCount: instanceCount];
|
instanceCount: instanceCount];
|
||||||
@ -371,7 +374,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
return;
|
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.
|
// 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) {
|
if (pipeline->getVkPrimitiveTopology() == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) {
|
||||||
@ -398,7 +401,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
} tessParams;
|
} tessParams;
|
||||||
uint32_t outControlPointCount = 0;
|
uint32_t outControlPointCount = 0;
|
||||||
if (pipeline->isTessellationPipeline()) {
|
if (pipeline->isTessellationPipeline()) {
|
||||||
tessParams.inControlPointCount = pipeline->getInputControlPointCount();
|
tessParams.inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints();
|
||||||
outControlPointCount = pipeline->getOutputControlPointCount();
|
outControlPointCount = pipeline->getOutputControlPointCount();
|
||||||
tessParams.patchCount = mvkCeilingDivide(_indexCount, tessParams.inControlPointCount) * _instanceCount;
|
tessParams.patchCount = mvkCeilingDivide(_indexCount, tessParams.inControlPointCount) * _instanceCount;
|
||||||
}
|
}
|
||||||
@ -530,7 +533,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
uint32_t instanceCount = _instanceCount * viewCount;
|
uint32_t instanceCount = _instanceCount * viewCount;
|
||||||
cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _firstInstance);
|
cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _firstInstance);
|
||||||
if (cmdEncoder->_pDeviceMetalFeatures->baseVertexInstanceDrawing) {
|
if (cmdEncoder->_pDeviceMetalFeatures->baseVertexInstanceDrawing) {
|
||||||
[cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_mtlPrimitiveType
|
[cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_renderingState.getPrimitiveType()
|
||||||
indexCount: _indexCount
|
indexCount: _indexCount
|
||||||
indexType: (MTLIndexType)ibb.mtlIndexType
|
indexType: (MTLIndexType)ibb.mtlIndexType
|
||||||
indexBuffer: ibb.mtlBuffer
|
indexBuffer: ibb.mtlBuffer
|
||||||
@ -539,7 +542,7 @@ void MVKCmdDrawIndexed::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
baseVertex: _vertexOffset
|
baseVertex: _vertexOffset
|
||||||
baseInstance: _firstInstance];
|
baseInstance: _firstInstance];
|
||||||
} else {
|
} else {
|
||||||
[cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_mtlPrimitiveType
|
[cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_renderingState.getPrimitiveType()
|
||||||
indexCount: _indexCount
|
indexCount: _indexCount
|
||||||
indexType: (MTLIndexType)ibb.mtlIndexType
|
indexType: (MTLIndexType)ibb.mtlIndexType
|
||||||
indexBuffer: ibb.mtlBuffer
|
indexBuffer: ibb.mtlBuffer
|
||||||
@ -646,7 +649,7 @@ void MVKCmdDrawIndirect::encodeIndexedIndirect(MVKCommandEncoder* cmdEncoder) {
|
|||||||
|
|
||||||
void MVKCmdDrawIndirect::encode(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.
|
// Metal doesn't support triangle fans, so encode it as indexed indirect triangles instead.
|
||||||
if (pipeline->getVkPrimitiveTopology() == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) {
|
if (pipeline->getVkPrimitiveTopology() == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) {
|
||||||
@ -683,7 +686,7 @@ void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
// encoding and execution. So we don't know how big to make the buffers.
|
// 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.
|
// We must assume an arbitrarily large number of vertices may be submitted.
|
||||||
// But not too many, or we'll exhaust available VRAM.
|
// But not too many, or we'll exhaust available VRAM.
|
||||||
inControlPointCount = pipeline->getInputControlPointCount();
|
inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints();
|
||||||
outControlPointCount = pipeline->getOutputControlPointCount();
|
outControlPointCount = pipeline->getOutputControlPointCount();
|
||||||
vertexCount = kMVKMaxDrawIndirectVertexCount;
|
vertexCount = kMVKMaxDrawIndirectVertexCount;
|
||||||
patchCount = mvkCeilingDivide(vertexCount, inControlPointCount);
|
patchCount = mvkCeilingDivide(vertexCount, inControlPointCount);
|
||||||
@ -925,7 +928,7 @@ void MVKCmdDrawIndirect::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
cmdEncoder->_graphicsResourcesState.beginMetalRenderPass();
|
cmdEncoder->_graphicsResourcesState.beginMetalRenderPass();
|
||||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->beginMetalRenderPass();
|
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->beginMetalRenderPass();
|
||||||
} else {
|
} else {
|
||||||
[cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_mtlPrimitiveType
|
[cmdEncoder->_mtlRenderEncoder drawPrimitives: cmdEncoder->_renderingState.getPrimitiveType()
|
||||||
indirectBuffer: mtlIndBuff
|
indirectBuffer: mtlIndBuff
|
||||||
indirectBufferOffset: mtlIndBuffOfst];
|
indirectBufferOffset: mtlIndBuffOfst];
|
||||||
mtlIndBuffOfst += needsInstanceAdjustment ? sizeof(MTLDrawPrimitivesIndirectArguments) : _mtlIndirectBufferStride;
|
mtlIndBuffOfst += needsInstanceAdjustment ? sizeof(MTLDrawPrimitivesIndirectArguments) : _mtlIndirectBufferStride;
|
||||||
@ -996,7 +999,7 @@ void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder, const MVKI
|
|||||||
|
|
||||||
MVKIndexMTLBufferBinding ibb = ibbOrig;
|
MVKIndexMTLBufferBinding ibb = ibbOrig;
|
||||||
MVKIndexMTLBufferBinding ibbTriFan = ibb;
|
MVKIndexMTLBufferBinding ibbTriFan = ibb;
|
||||||
auto* pipeline = (MVKGraphicsPipeline*)cmdEncoder->_graphicsPipelineState.getPipeline();
|
auto* pipeline = cmdEncoder->_graphicsPipelineState.getGraphicsPipeline();
|
||||||
|
|
||||||
MVKVertexAdjustments vtxAdjmts;
|
MVKVertexAdjustments vtxAdjmts;
|
||||||
vtxAdjmts.mtlIndexType = ibb.mtlIndexType;
|
vtxAdjmts.mtlIndexType = ibb.mtlIndexType;
|
||||||
@ -1031,7 +1034,7 @@ void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder, const MVKI
|
|||||||
// encoding and execution. So we don't know how big to make the buffers.
|
// 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.
|
// We must assume an arbitrarily large number of vertices may be submitted.
|
||||||
// But not too many, or we'll exhaust available VRAM.
|
// But not too many, or we'll exhaust available VRAM.
|
||||||
inControlPointCount = pipeline->getInputControlPointCount();
|
inControlPointCount = cmdEncoder->_graphicsPipelineState.getPatchControlPoints();
|
||||||
outControlPointCount = pipeline->getOutputControlPointCount();
|
outControlPointCount = pipeline->getOutputControlPointCount();
|
||||||
vertexCount = kMVKMaxDrawIndirectVertexCount;
|
vertexCount = kMVKMaxDrawIndirectVertexCount;
|
||||||
patchCount = mvkCeilingDivide(vertexCount, inControlPointCount);
|
patchCount = mvkCeilingDivide(vertexCount, inControlPointCount);
|
||||||
@ -1312,7 +1315,7 @@ void MVKCmdDrawIndexedIndirect::encode(MVKCommandEncoder* cmdEncoder, const MVKI
|
|||||||
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->beginMetalRenderPass();
|
cmdEncoder->getPushConstants(VK_SHADER_STAGE_VERTEX_BIT)->beginMetalRenderPass();
|
||||||
} else {
|
} else {
|
||||||
cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _directCmdFirstInstance);
|
cmdEncoder->_graphicsResourcesState.offsetZeroDivisorVertexBuffers(stage, pipeline, _directCmdFirstInstance);
|
||||||
[cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_mtlPrimitiveType
|
[cmdEncoder->_mtlRenderEncoder drawIndexedPrimitives: cmdEncoder->_renderingState.getPrimitiveType()
|
||||||
indexType: (MTLIndexType)ibb.mtlIndexType
|
indexType: (MTLIndexType)ibb.mtlIndexType
|
||||||
indexBuffer: ibb.mtlBuffer
|
indexBuffer: ibb.mtlBuffer
|
||||||
indexBufferOffset: ibb.offset
|
indexBufferOffset: ibb.offset
|
||||||
|
@ -30,6 +30,34 @@ class MVKDescriptorSet;
|
|||||||
class MVKDescriptorUpdateTemplate;
|
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 -
|
||||||
#pragma mark MVKCmdPipelineBarrier
|
#pragma mark MVKCmdPipelineBarrier
|
||||||
|
|
||||||
|
@ -26,6 +26,33 @@
|
|||||||
#include "mvk_datatypes.hpp"
|
#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 -
|
||||||
#pragma mark MVKCmdPipelineBarrier
|
#pragma mark MVKCmdPipelineBarrier
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* MVKCmdRenderPass.h
|
* MVKCmdRendering.h
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com)
|
* 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 -
|
||||||
#pragma mark MVKCmdSetViewport
|
#pragma mark MVKCmdSetViewport
|
||||||
|
|
||||||
@ -295,25 +267,6 @@ typedef MVKCmdSetScissor<1> MVKCmdSetScissor1;
|
|||||||
typedef MVKCmdSetScissor<kMVKMaxViewportScissorCount> MVKCmdSetScissorMulti;
|
typedef MVKCmdSetScissor<kMVKMaxViewportScissorCount> MVKCmdSetScissorMulti;
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark MVKCmdSetLineWidth
|
|
||||||
|
|
||||||
/** Vulkan command to set the line width. */
|
|
||||||
class MVKCmdSetLineWidth : public MVKCommand {
|
|
||||||
|
|
||||||
public:
|
|
||||||
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
|
||||||
float lineWidth);
|
|
||||||
|
|
||||||
void encode(MVKCommandEncoder* cmdEncoder) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
|
||||||
|
|
||||||
float _lineWidth;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKCmdSetDepthBias
|
#pragma mark MVKCmdSetDepthBias
|
||||||
|
|
||||||
@ -337,6 +290,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 -
|
||||||
#pragma mark MVKCmdSetBlendConstants
|
#pragma mark MVKCmdSetBlendConstants
|
||||||
|
|
||||||
@ -352,31 +324,110 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
float _red;
|
float _blendConstants[4] = {};
|
||||||
float _green;
|
|
||||||
float _blue;
|
|
||||||
float _alpha;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKCmdSetDepthBounds
|
#pragma mark MVKCmdSetDepthTestEnable
|
||||||
|
|
||||||
/** Vulkan command to set depth bounds. */
|
/** Vulkan command to dynamically enable depth testing. */
|
||||||
class MVKCmdSetDepthBounds : public MVKCommand {
|
class MVKCmdSetDepthTestEnable : public MVKCommand {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
float minDepthBounds,
|
VkBool32 depthTestEnable);
|
||||||
float maxDepthBounds);
|
|
||||||
|
|
||||||
void encode(MVKCommandEncoder* cmdEncoder) override;
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
float _minDepthBounds;
|
VkBool32 _depthTestEnable;
|
||||||
float _maxDepthBounds;
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetDepthWriteEnable
|
||||||
|
|
||||||
|
/** Vulkan command to dynamically enable depth writing. */
|
||||||
|
class MVKCmdSetDepthWriteEnable : public MVKCommand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkBool32 depthWriteEnable);
|
||||||
|
|
||||||
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
|
VkBool32 _depthWriteEnable;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetDepthCompareOp
|
||||||
|
|
||||||
|
/** Vulkan command to dynamically set the depth compare operation. */
|
||||||
|
class MVKCmdSetDepthCompareOp : public MVKCommand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkCompareOp depthCompareOp);
|
||||||
|
|
||||||
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
|
VkCompareOp _depthCompareOp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetStencilTestEnable
|
||||||
|
|
||||||
|
/** Vulkan command to dynamically enable stencil testing. */
|
||||||
|
class MVKCmdSetStencilTestEnable : public MVKCommand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkBool32 stencilTestEnable);
|
||||||
|
|
||||||
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
|
VkBool32 _stencilTestEnable;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetStencilOp
|
||||||
|
|
||||||
|
/** Vulkan command to dynamically set the stencil operations. */
|
||||||
|
class MVKCmdSetStencilOp : public MVKCommand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkStencilFaceFlags faceMask,
|
||||||
|
VkStencilOp failOp,
|
||||||
|
VkStencilOp passOp,
|
||||||
|
VkStencilOp depthFailOp,
|
||||||
|
VkCompareOp compareOp);
|
||||||
|
|
||||||
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
|
VkStencilFaceFlags _faceMask;
|
||||||
|
VkStencilOp _failOp;
|
||||||
|
VkStencilOp _passOp;
|
||||||
|
VkStencilOp _depthFailOp;
|
||||||
|
VkCompareOp _compareOp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -442,3 +493,115 @@ protected:
|
|||||||
uint32_t _stencilReference;
|
uint32_t _stencilReference;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetCullMode
|
||||||
|
|
||||||
|
/** Vulkan command to dynamically set the cull mode. */
|
||||||
|
class MVKCmdSetCullMode : public MVKCommand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkCullModeFlags cullMode);
|
||||||
|
|
||||||
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
|
VkCullModeFlags _cullMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetFrontFace
|
||||||
|
|
||||||
|
/** Vulkan command to dynamically set the front facing winding order. */
|
||||||
|
class MVKCmdSetFrontFace : public MVKCommand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkFrontFace frontFace);
|
||||||
|
|
||||||
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
|
VkFrontFace _frontFace;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
/** Vulkan command to dynamically set the primitive topology. */
|
||||||
|
class MVKCmdSetPrimitiveTopology : public MVKCommand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VkResult setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkPrimitiveTopology primitiveTopology);
|
||||||
|
|
||||||
|
void encode(MVKCommandEncoder* cmdEncoder) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MVKCommandTypePool<MVKCommand>* getTypePool(MVKCommandPool* cmdPool) override;
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* MVKCmdRenderPass.mm
|
* MVKCmdRendering.mm
|
||||||
*
|
*
|
||||||
* Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com)
|
* Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com)
|
||||||
*
|
*
|
||||||
@ -16,7 +16,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MVKCmdRenderPass.h"
|
#include "MVKCmdRendering.h"
|
||||||
#include "MVKCommandBuffer.h"
|
#include "MVKCommandBuffer.h"
|
||||||
#include "MVKCommandPool.h"
|
#include "MVKCommandPool.h"
|
||||||
#include "MVKFramebuffer.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 -
|
||||||
#pragma mark MVKCmdSetViewport
|
#pragma mark MVKCmdSetViewport
|
||||||
|
|
||||||
@ -278,7 +251,7 @@ VkResult MVKCmdSetViewport<N>::setContent(MVKCommandBuffer* cmdBuff,
|
|||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
void MVKCmdSetViewport<N>::encode(MVKCommandEncoder* cmdEncoder) {
|
void MVKCmdSetViewport<N>::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
cmdEncoder->_viewportState.setViewports(_viewports.contents(), _firstViewport, true);
|
cmdEncoder->_renderingState.setViewports(_viewports.contents(), _firstViewport, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template class MVKCmdSetViewport<1>;
|
template class MVKCmdSetViewport<1>;
|
||||||
@ -305,31 +278,13 @@ VkResult MVKCmdSetScissor<N>::setContent(MVKCommandBuffer* cmdBuff,
|
|||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
void MVKCmdSetScissor<N>::encode(MVKCommandEncoder* cmdEncoder) {
|
void MVKCmdSetScissor<N>::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
cmdEncoder->_scissorState.setScissors(_scissors.contents(), _firstScissor, true);
|
cmdEncoder->_renderingState.setScissors(_scissors.contents(), _firstScissor, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
template class MVKCmdSetScissor<1>;
|
template class MVKCmdSetScissor<1>;
|
||||||
template class MVKCmdSetScissor<kMVKMaxViewportScissorCount>;
|
template class MVKCmdSetScissor<kMVKMaxViewportScissorCount>;
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark MVKCmdSetLineWidth
|
|
||||||
|
|
||||||
VkResult MVKCmdSetLineWidth::setContent(MVKCommandBuffer* cmdBuff,
|
|
||||||
float lineWidth) {
|
|
||||||
_lineWidth = lineWidth;
|
|
||||||
|
|
||||||
// Validate
|
|
||||||
if (_lineWidth != 1.0 || cmdBuff->getDevice()->_enabledFeatures.wideLines) {
|
|
||||||
return cmdBuff->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdSetLineWidth(): The current device does not support wide lines.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return VK_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MVKCmdSetLineWidth::encode(MVKCommandEncoder* cmdEncoder) {}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKCmdSetDepthBias
|
#pragma mark MVKCmdSetDepthBias
|
||||||
|
|
||||||
@ -345,48 +300,116 @@ VkResult MVKCmdSetDepthBias::setContent(MVKCommandBuffer* cmdBuff,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MVKCmdSetDepthBias::encode(MVKCommandEncoder* cmdEncoder) {
|
void MVKCmdSetDepthBias::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
cmdEncoder->_depthBiasState.setDepthBias(_depthBiasConstantFactor,
|
cmdEncoder->_renderingState.setDepthBias(_depthBiasConstantFactor,
|
||||||
_depthBiasSlopeFactor,
|
_depthBiasSlopeFactor,
|
||||||
_depthBiasClamp);
|
_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 -
|
||||||
#pragma mark MVKCmdSetBlendConstants
|
#pragma mark MVKCmdSetBlendConstants
|
||||||
|
|
||||||
VkResult MVKCmdSetBlendConstants::setContent(MVKCommandBuffer* cmdBuff,
|
VkResult MVKCmdSetBlendConstants::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
const float blendConst[4]) {
|
const float blendConst[4]) {
|
||||||
_red = blendConst[0];
|
mvkCopy(_blendConstants, blendConst, 4);
|
||||||
_green = blendConst[1];
|
|
||||||
_blue = blendConst[2];
|
|
||||||
_alpha = blendConst[3];
|
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKCmdSetBlendConstants::encode(MVKCommandEncoder* cmdEncoder) {
|
void MVKCmdSetBlendConstants::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
cmdEncoder->_blendColorState.setBlendColor(_red, _green, _blue, _alpha, true);
|
cmdEncoder->_renderingState.setBlendConstants(_blendConstants, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKCmdSetDepthBounds
|
#pragma mark MVKCmdSetDepthTestEnable
|
||||||
|
|
||||||
VkResult MVKCmdSetDepthBounds::setContent(MVKCommandBuffer* cmdBuff,
|
|
||||||
float minDepthBounds,
|
|
||||||
float maxDepthBounds) {
|
|
||||||
_minDepthBounds = minDepthBounds;
|
|
||||||
_maxDepthBounds = maxDepthBounds;
|
|
||||||
|
|
||||||
// Validate
|
|
||||||
if (cmdBuff->getDevice()->_enabledFeatures.depthBounds) {
|
|
||||||
return cmdBuff->reportError(VK_ERROR_FEATURE_NOT_PRESENT, "vkCmdSetDepthBounds(): The current device does not support setting depth bounds.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
VkResult MVKCmdSetDepthTestEnable::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkBool32 depthTestEnable) {
|
||||||
|
_depthTestEnable = depthTestEnable;
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKCmdSetDepthBounds::encode(MVKCommandEncoder* cmdEncoder) {}
|
void MVKCmdSetDepthTestEnable::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
|
cmdEncoder->_depthStencilState.setDepthTestEnable(_depthTestEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetDepthWriteEnable
|
||||||
|
|
||||||
|
VkResult MVKCmdSetDepthWriteEnable::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkBool32 depthWriteEnable) {
|
||||||
|
_depthWriteEnable = depthWriteEnable;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKCmdSetDepthWriteEnable::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
|
cmdEncoder->_depthStencilState.setDepthWriteEnable(_depthWriteEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetDepthCompareOp
|
||||||
|
|
||||||
|
VkResult MVKCmdSetDepthCompareOp::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkCompareOp depthCompareOp) {
|
||||||
|
_depthCompareOp = depthCompareOp;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKCmdSetDepthCompareOp::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
|
cmdEncoder->_depthStencilState.setDepthCompareOp(_depthCompareOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetStencilTestEnable
|
||||||
|
|
||||||
|
VkResult MVKCmdSetStencilTestEnable::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkBool32 stencilTestEnable) {
|
||||||
|
_stencilTestEnable = stencilTestEnable;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKCmdSetStencilTestEnable::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
|
cmdEncoder->_depthStencilState.setStencilTestEnable(_stencilTestEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetStencilOp
|
||||||
|
|
||||||
|
VkResult MVKCmdSetStencilOp::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkStencilFaceFlags faceMask,
|
||||||
|
VkStencilOp failOp,
|
||||||
|
VkStencilOp passOp,
|
||||||
|
VkStencilOp depthFailOp,
|
||||||
|
VkCompareOp compareOp) {
|
||||||
|
_faceMask = faceMask;
|
||||||
|
_failOp = failOp;
|
||||||
|
_passOp = passOp;
|
||||||
|
_depthFailOp = depthFailOp;
|
||||||
|
_compareOp = compareOp;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKCmdSetStencilOp::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
|
cmdEncoder->_depthStencilState.setStencilOp(_faceMask, _failOp, _passOp, _depthFailOp, _compareOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
@ -436,6 +459,95 @@ VkResult MVKCmdSetStencilReference::setContent(MVKCommandBuffer* cmdBuff,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MVKCmdSetStencilReference::encode(MVKCommandEncoder* cmdEncoder) {
|
void MVKCmdSetStencilReference::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
cmdEncoder->_stencilReferenceValueState.setReferenceValues(_faceMask, _stencilReference);
|
cmdEncoder->_renderingState.setStencilReferenceValues(_faceMask, _stencilReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetCullMode
|
||||||
|
|
||||||
|
VkResult MVKCmdSetCullMode::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkCullModeFlags cullMode) {
|
||||||
|
_cullMode = cullMode;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKCmdSetCullMode::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
|
cmdEncoder->_renderingState.setCullMode(_cullMode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetFrontFace
|
||||||
|
|
||||||
|
VkResult MVKCmdSetFrontFace::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkFrontFace frontFace) {
|
||||||
|
_frontFace = frontFace;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKCmdSetFrontFace::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark MVKCmdSetPrimitiveTopology
|
||||||
|
|
||||||
|
VkResult MVKCmdSetPrimitiveTopology::setContent(MVKCommandBuffer* cmdBuff,
|
||||||
|
VkPrimitiveTopology primitiveTopology) {
|
||||||
|
_primitiveTopology = primitiveTopology;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKCmdSetPrimitiveTopology::encode(MVKCommandEncoder* cmdEncoder) {
|
||||||
|
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);
|
||||||
|
}
|
@ -1507,10 +1507,7 @@ void MVKCmdClearAttachments<N>::encode(MVKCommandEncoder* cmdEncoder) {
|
|||||||
// Return to the previous rendering state on the next render activity
|
// Return to the previous rendering state on the next render activity
|
||||||
cmdEncoder->_graphicsPipelineState.markDirty();
|
cmdEncoder->_graphicsPipelineState.markDirty();
|
||||||
cmdEncoder->_depthStencilState.markDirty();
|
cmdEncoder->_depthStencilState.markDirty();
|
||||||
cmdEncoder->_stencilReferenceValueState.markDirty();
|
cmdEncoder->_renderingState.markDirty();
|
||||||
cmdEncoder->_depthBiasState.markDirty();
|
|
||||||
cmdEncoder->_viewportState.markDirty();
|
|
||||||
cmdEncoder->_scissorState.markDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
|
@ -300,14 +300,11 @@ public:
|
|||||||
/** Encodes an operation to signal an event to a status. */
|
/** Encodes an operation to signal an event to a status. */
|
||||||
void signalEvent(MVKEvent* mvkEvent, bool status);
|
void signalEvent(MVKEvent* mvkEvent, bool status);
|
||||||
|
|
||||||
/**
|
/** Clips the rect to ensure it fits inside the render area. */
|
||||||
* If a pipeline is currently bound, returns whether the current pipeline permits dynamic
|
VkRect2D clipToRenderArea(VkRect2D rect);
|
||||||
* setting of the specified state. If no pipeline is currently bound, returns true.
|
|
||||||
*/
|
|
||||||
bool supportsDynamicState(VkDynamicState state);
|
|
||||||
|
|
||||||
/** Clips the scissor to ensure it fits inside the render area. */
|
/** Clips the scissor to ensure it fits inside the render area. */
|
||||||
VkRect2D clipToRenderArea(VkRect2D scissor);
|
MTLScissorRect clipToRenderArea(MTLScissorRect scissor);
|
||||||
|
|
||||||
/** Called by each graphics draw command to establish any outstanding state just prior to performing the draw. */
|
/** Called by each graphics draw command to establish any outstanding state just prior to performing the draw. */
|
||||||
void finalizeDrawState(MVKGraphicsStage stage);
|
void finalizeDrawState(MVKGraphicsStage stage);
|
||||||
@ -361,6 +358,9 @@ public:
|
|||||||
/** Returns the push constants associated with the specified shader stage. */
|
/** Returns the push constants associated with the specified shader stage. */
|
||||||
MVKPushConstantsCommandEncoderState* getPushConstants(VkShaderStageFlagBits shaderStage);
|
MVKPushConstantsCommandEncoderState* getPushConstants(VkShaderStageFlagBits shaderStage);
|
||||||
|
|
||||||
|
/** Encode the buffer binding as a vertex attribute buffer. */
|
||||||
|
void encodeVertexAttributeBuffer(MVKMTLBufferBinding& b, bool isDynamicStride);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy bytes into the Metal encoder at a Metal vertex buffer index, and optionally indicate
|
* Copy bytes into the Metal encoder at a Metal vertex buffer index, and optionally indicate
|
||||||
* that this binding might override a desriptor binding. If so, the descriptor binding will
|
* that this binding might override a desriptor binding. If so, the descriptor binding will
|
||||||
@ -435,37 +435,22 @@ public:
|
|||||||
id<MTLRenderCommandEncoder> _mtlRenderEncoder;
|
id<MTLRenderCommandEncoder> _mtlRenderEncoder;
|
||||||
|
|
||||||
/** Tracks the current graphics pipeline bound to the encoder. */
|
/** Tracks the current graphics pipeline bound to the encoder. */
|
||||||
MVKPipelineCommandEncoderState _graphicsPipelineState;
|
MVKGraphicsPipelineCommandEncoderState _graphicsPipelineState;
|
||||||
|
|
||||||
/** Tracks the current compute pipeline bound to the encoder. */
|
|
||||||
MVKPipelineCommandEncoderState _computePipelineState;
|
|
||||||
|
|
||||||
/** Tracks the current viewport state of the encoder. */
|
|
||||||
MVKViewportCommandEncoderState _viewportState;
|
|
||||||
|
|
||||||
/** Tracks the current scissor state of the encoder. */
|
|
||||||
MVKScissorCommandEncoderState _scissorState;
|
|
||||||
|
|
||||||
/** Tracks the current depth bias state of the encoder. */
|
|
||||||
MVKDepthBiasCommandEncoderState _depthBiasState;
|
|
||||||
|
|
||||||
/** Tracks the current blend color state of the encoder. */
|
|
||||||
MVKBlendColorCommandEncoderState _blendColorState;
|
|
||||||
|
|
||||||
/** Tracks the current depth stencil state of the encoder. */
|
|
||||||
MVKDepthStencilCommandEncoderState _depthStencilState;
|
|
||||||
|
|
||||||
/** Tracks the current stencil reference value state of the encoder. */
|
|
||||||
MVKStencilReferenceValueCommandEncoderState _stencilReferenceValueState;
|
|
||||||
|
|
||||||
/** Tracks the current graphics resources state of the encoder. */
|
/** Tracks the current graphics resources state of the encoder. */
|
||||||
MVKGraphicsResourcesCommandEncoderState _graphicsResourcesState;
|
MVKGraphicsResourcesCommandEncoderState _graphicsResourcesState;
|
||||||
|
|
||||||
|
/** Tracks the current compute pipeline bound to the encoder. */
|
||||||
|
MVKComputePipelineCommandEncoderState _computePipelineState;
|
||||||
|
|
||||||
/** Tracks the current compute resources state of the encoder. */
|
/** Tracks the current compute resources state of the encoder. */
|
||||||
MVKComputeResourcesCommandEncoderState _computeResourcesState;
|
MVKComputeResourcesCommandEncoderState _computeResourcesState;
|
||||||
|
|
||||||
/** The type of primitive that will be rendered. */
|
/** Tracks the current depth stencil state of the encoder. */
|
||||||
MTLPrimitiveType _mtlPrimitiveType;
|
MVKDepthStencilCommandEncoderState _depthStencilState;
|
||||||
|
|
||||||
|
/** Tracks the current rendering states of the encoder. */
|
||||||
|
MVKRenderingCommandEncoderState _renderingState;
|
||||||
|
|
||||||
/** The size of the threadgroup for the compute shader. */
|
/** The size of the threadgroup for the compute shader. */
|
||||||
MTLSize _mtlThreadgroupSize;
|
MTLSize _mtlThreadgroupSize;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "MVKFoundation.h"
|
#include "MVKFoundation.h"
|
||||||
#include "MTLRenderPassDescriptor+MoltenVK.h"
|
#include "MTLRenderPassDescriptor+MoltenVK.h"
|
||||||
#include "MVKCmdDraw.h"
|
#include "MVKCmdDraw.h"
|
||||||
#include "MVKCmdRenderPass.h"
|
#include "MVKCmdRendering.h"
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -607,16 +607,12 @@ void MVKCommandEncoder::beginMetalRenderPass(MVKCommandUse cmdUse) {
|
|||||||
|
|
||||||
_graphicsPipelineState.beginMetalRenderPass();
|
_graphicsPipelineState.beginMetalRenderPass();
|
||||||
_graphicsResourcesState.beginMetalRenderPass();
|
_graphicsResourcesState.beginMetalRenderPass();
|
||||||
_viewportState.beginMetalRenderPass();
|
_depthStencilState.beginMetalRenderPass();
|
||||||
_scissorState.beginMetalRenderPass();
|
_renderingState.beginMetalRenderPass();
|
||||||
_depthBiasState.beginMetalRenderPass();
|
|
||||||
_blendColorState.beginMetalRenderPass();
|
|
||||||
_vertexPushConstants.beginMetalRenderPass();
|
_vertexPushConstants.beginMetalRenderPass();
|
||||||
_tessCtlPushConstants.beginMetalRenderPass();
|
_tessCtlPushConstants.beginMetalRenderPass();
|
||||||
_tessEvalPushConstants.beginMetalRenderPass();
|
_tessEvalPushConstants.beginMetalRenderPass();
|
||||||
_fragmentPushConstants.beginMetalRenderPass();
|
_fragmentPushConstants.beginMetalRenderPass();
|
||||||
_depthStencilState.beginMetalRenderPass();
|
|
||||||
_stencilReferenceValueState.beginMetalRenderPass();
|
|
||||||
_occlusionQueryState.beginMetalRenderPass();
|
_occlusionQueryState.beginMetalRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,24 +702,23 @@ void MVKCommandEncoder::signalEvent(MVKEvent* mvkEvent, bool status) {
|
|||||||
mvkEvent->encodeSignal(_mtlCmdBuffer, status);
|
mvkEvent->encodeSignal(_mtlCmdBuffer, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MVKCommandEncoder::supportsDynamicState(VkDynamicState state) {
|
VkRect2D MVKCommandEncoder::clipToRenderArea(VkRect2D rect) {
|
||||||
MVKGraphicsPipeline* gpl = (MVKGraphicsPipeline*)_graphicsPipelineState.getPipeline();
|
|
||||||
return !gpl || gpl->supportsDynamicState(state);
|
uint32_t raLeft = max(_renderArea.offset.x, 0);
|
||||||
|
uint32_t raRight = raLeft + _renderArea.extent.width;
|
||||||
|
uint32_t raBottom = max(_renderArea.offset.y, 0);
|
||||||
|
uint32_t raTop = raBottom + _renderArea.extent.height;
|
||||||
|
|
||||||
|
rect.offset.x = mvkClamp<uint32_t>(rect.offset.x, raLeft, max(raRight - 1, raLeft));
|
||||||
|
rect.offset.y = mvkClamp<uint32_t>(rect.offset.y, raBottom, max(raTop - 1, raBottom));
|
||||||
|
rect.extent.width = min<uint32_t>(rect.extent.width, raRight - rect.offset.x);
|
||||||
|
rect.extent.height = min<uint32_t>(rect.extent.height, raTop - rect.offset.y);
|
||||||
|
|
||||||
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkRect2D MVKCommandEncoder::clipToRenderArea(VkRect2D scissor) {
|
MTLScissorRect MVKCommandEncoder::clipToRenderArea(MTLScissorRect scissor) {
|
||||||
|
return mvkMTLScissorRectFromVkRect2D(clipToRenderArea(mvkVkRect2DFromMTLScissorRect(scissor)));
|
||||||
int32_t raLeft = _renderArea.offset.x;
|
|
||||||
int32_t raRight = raLeft + _renderArea.extent.width;
|
|
||||||
int32_t raBottom = _renderArea.offset.y;
|
|
||||||
int32_t raTop = raBottom + _renderArea.extent.height;
|
|
||||||
|
|
||||||
scissor.offset.x = mvkClamp(scissor.offset.x, raLeft, max(raRight - 1, raLeft));
|
|
||||||
scissor.offset.y = mvkClamp(scissor.offset.y, raBottom, max(raTop - 1, raBottom));
|
|
||||||
scissor.extent.width = min<int32_t>(scissor.extent.width, raRight - scissor.offset.x);
|
|
||||||
scissor.extent.height = min<int32_t>(scissor.extent.height, raTop - scissor.offset.y);
|
|
||||||
|
|
||||||
return scissor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKCommandEncoder::finalizeDrawState(MVKGraphicsStage stage) {
|
void MVKCommandEncoder::finalizeDrawState(MVKGraphicsStage stage) {
|
||||||
@ -733,16 +728,12 @@ void MVKCommandEncoder::finalizeDrawState(MVKGraphicsStage stage) {
|
|||||||
}
|
}
|
||||||
_graphicsPipelineState.encode(stage); // Must do first..it sets others
|
_graphicsPipelineState.encode(stage); // Must do first..it sets others
|
||||||
_graphicsResourcesState.encode(stage); // Before push constants, to allow them to override.
|
_graphicsResourcesState.encode(stage); // Before push constants, to allow them to override.
|
||||||
_viewportState.encode(stage);
|
_depthStencilState.encode(stage);
|
||||||
_scissorState.encode(stage);
|
_renderingState.encode(stage);
|
||||||
_depthBiasState.encode(stage);
|
|
||||||
_blendColorState.encode(stage);
|
|
||||||
_vertexPushConstants.encode(stage);
|
_vertexPushConstants.encode(stage);
|
||||||
_tessCtlPushConstants.encode(stage);
|
_tessCtlPushConstants.encode(stage);
|
||||||
_tessEvalPushConstants.encode(stage);
|
_tessEvalPushConstants.encode(stage);
|
||||||
_fragmentPushConstants.encode(stage);
|
_fragmentPushConstants.encode(stage);
|
||||||
_depthStencilState.encode(stage);
|
|
||||||
_stencilReferenceValueState.encode(stage);
|
|
||||||
_occlusionQueryState.encode(stage);
|
_occlusionQueryState.encode(stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,16 +822,12 @@ void MVKCommandEncoder::endMetalRenderEncoding() {
|
|||||||
|
|
||||||
_graphicsPipelineState.endMetalRenderPass();
|
_graphicsPipelineState.endMetalRenderPass();
|
||||||
_graphicsResourcesState.endMetalRenderPass();
|
_graphicsResourcesState.endMetalRenderPass();
|
||||||
_viewportState.endMetalRenderPass();
|
_depthStencilState.endMetalRenderPass();
|
||||||
_scissorState.endMetalRenderPass();
|
_renderingState.endMetalRenderPass();
|
||||||
_depthBiasState.endMetalRenderPass();
|
|
||||||
_blendColorState.endMetalRenderPass();
|
|
||||||
_vertexPushConstants.endMetalRenderPass();
|
_vertexPushConstants.endMetalRenderPass();
|
||||||
_tessCtlPushConstants.endMetalRenderPass();
|
_tessCtlPushConstants.endMetalRenderPass();
|
||||||
_tessEvalPushConstants.endMetalRenderPass();
|
_tessEvalPushConstants.endMetalRenderPass();
|
||||||
_fragmentPushConstants.endMetalRenderPass();
|
_fragmentPushConstants.endMetalRenderPass();
|
||||||
_depthStencilState.endMetalRenderPass();
|
|
||||||
_stencilReferenceValueState.endMetalRenderPass();
|
|
||||||
_occlusionQueryState.endMetalRenderPass();
|
_occlusionQueryState.endMetalRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -932,6 +919,42 @@ void MVKCommandEncoder::setVertexBytes(id<MTLRenderCommandEncoder> mtlEncoder,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MVKCommandEncoder::encodeVertexAttributeBuffer(MVKMTLBufferBinding& b, bool isDynamicStride) {
|
||||||
|
if (_device->_pMetalFeatures->dynamicVertexStride) {
|
||||||
|
#if MVK_XCODE_15
|
||||||
|
NSUInteger mtlStride = isDynamicStride ? b.stride : MTLAttributeStrideStatic;
|
||||||
|
if (b.isInline) {
|
||||||
|
[_mtlRenderEncoder setVertexBytes: b.mtlBytes
|
||||||
|
length: b.size
|
||||||
|
attributeStride: mtlStride
|
||||||
|
atIndex: b.index];
|
||||||
|
} else if (b.justOffset) {
|
||||||
|
[_mtlRenderEncoder setVertexBufferOffset: b.offset
|
||||||
|
attributeStride: mtlStride
|
||||||
|
atIndex: b.index];
|
||||||
|
} else {
|
||||||
|
[_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
|
||||||
|
offset: b.offset
|
||||||
|
attributeStride: mtlStride
|
||||||
|
atIndex: b.index];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
if (b.isInline) {
|
||||||
|
[_mtlRenderEncoder setVertexBytes: b.mtlBytes
|
||||||
|
length: b.size
|
||||||
|
atIndex: b.index];
|
||||||
|
} else if (b.justOffset) {
|
||||||
|
[_mtlRenderEncoder setVertexBufferOffset: b.offset
|
||||||
|
atIndex: b.index];
|
||||||
|
} else {
|
||||||
|
[_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
|
||||||
|
offset: b.offset
|
||||||
|
atIndex: b.index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MVKCommandEncoder::setFragmentBytes(id<MTLRenderCommandEncoder> mtlEncoder,
|
void MVKCommandEncoder::setFragmentBytes(id<MTLRenderCommandEncoder> mtlEncoder,
|
||||||
const void* bytes,
|
const void* bytes,
|
||||||
NSUInteger length,
|
NSUInteger length,
|
||||||
@ -1133,15 +1156,11 @@ MVKCommandEncoder::MVKCommandEncoder(MVKCommandBuffer* cmdBuffer,
|
|||||||
MVKPrefillMetalCommandBuffersStyle prefillStyle) : MVKBaseDeviceObject(cmdBuffer->getDevice()),
|
MVKPrefillMetalCommandBuffersStyle prefillStyle) : MVKBaseDeviceObject(cmdBuffer->getDevice()),
|
||||||
_cmdBuffer(cmdBuffer),
|
_cmdBuffer(cmdBuffer),
|
||||||
_graphicsPipelineState(this),
|
_graphicsPipelineState(this),
|
||||||
_computePipelineState(this),
|
|
||||||
_viewportState(this),
|
|
||||||
_scissorState(this),
|
|
||||||
_depthBiasState(this),
|
|
||||||
_blendColorState(this),
|
|
||||||
_depthStencilState(this),
|
|
||||||
_stencilReferenceValueState(this),
|
|
||||||
_graphicsResourcesState(this),
|
_graphicsResourcesState(this),
|
||||||
|
_computePipelineState(this),
|
||||||
_computeResourcesState(this),
|
_computeResourcesState(this),
|
||||||
|
_depthStencilState(this),
|
||||||
|
_renderingState(this),
|
||||||
_vertexPushConstants(this, VK_SHADER_STAGE_VERTEX_BIT),
|
_vertexPushConstants(this, VK_SHADER_STAGE_VERTEX_BIT),
|
||||||
_tessCtlPushConstants(this, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
|
_tessCtlPushConstants(this, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
|
||||||
_tessEvalPushConstants(this, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
|
_tessEvalPushConstants(this, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "MVKMTLResourceBindings.h"
|
#include "MVKMTLResourceBindings.h"
|
||||||
#include "MVKCommandResourceFactory.h"
|
#include "MVKCommandResourceFactory.h"
|
||||||
#include "MVKDevice.h"
|
#include "MVKDevice.h"
|
||||||
|
#include "MVKPipeline.h"
|
||||||
#include "MVKDescriptor.h"
|
#include "MVKDescriptor.h"
|
||||||
#include "MVKSmallVector.h"
|
#include "MVKSmallVector.h"
|
||||||
#include "MVKBitArray.h"
|
#include "MVKBitArray.h"
|
||||||
@ -81,7 +82,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* If the content of this instance is dirty, marks this instance as no longer dirty
|
* If the content of this instance is dirty, marks this instance as no longer dirty
|
||||||
* and calls the encodeImpl() function to encode the content onto the Metal encoder.
|
* and calls the encodeImpl() function to encode the content onto the Metal encoder.
|
||||||
* Marking dirty is done in advance so that subclass encodeImpl() implementations
|
* Marking clean is done in advance so that subclass encodeImpl() implementations
|
||||||
* can override to leave this instance in a dirty state.
|
* can override to leave this instance in a dirty state.
|
||||||
* Subclasses must override the encodeImpl() function to do the actual work.
|
* Subclasses must override the encodeImpl() function to do the actual work.
|
||||||
*/
|
*/
|
||||||
@ -96,8 +97,18 @@ public:
|
|||||||
MVKCommandEncoderState(MVKCommandEncoder* cmdEncoder) : _cmdEncoder(cmdEncoder) {}
|
MVKCommandEncoderState(MVKCommandEncoder* cmdEncoder) : _cmdEncoder(cmdEncoder) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
enum StateScope {
|
||||||
|
Static = 0,
|
||||||
|
Dynamic,
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
virtual void encodeImpl(uint32_t stage) = 0;
|
virtual void encodeImpl(uint32_t stage) = 0;
|
||||||
MVKDevice* getDevice();
|
MVKDevice* getDevice();
|
||||||
|
bool isDynamicState(MVKRenderStateType state);
|
||||||
|
template <typename T> T& getContent(T* iVarAry, MVKRenderStateType state) {
|
||||||
|
return iVarAry[isDynamicState(state) ? StateScope::Dynamic : StateScope::Static];
|
||||||
|
}
|
||||||
|
|
||||||
MVKCommandEncoder* _cmdEncoder;
|
MVKCommandEncoder* _cmdEncoder;
|
||||||
bool _isDirty = false;
|
bool _isDirty = false;
|
||||||
@ -108,20 +119,15 @@ protected:
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKPipelineCommandEncoderState
|
#pragma mark MVKPipelineCommandEncoderState
|
||||||
|
|
||||||
/** Holds encoder state established by pipeline commands. */
|
/** Abstract class to hold encoder state established by pipeline commands. */
|
||||||
class MVKPipelineCommandEncoderState : public MVKCommandEncoderState {
|
class MVKPipelineCommandEncoderState : public MVKCommandEncoderState {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual void bindPipeline(MVKPipeline* pipeline);
|
||||||
|
|
||||||
/** Binds the pipeline. */
|
|
||||||
void bindPipeline(MVKPipeline* pipeline);
|
|
||||||
|
|
||||||
/** Returns the currently bound pipeline. */
|
|
||||||
MVKPipeline* getPipeline();
|
MVKPipeline* getPipeline();
|
||||||
|
|
||||||
/** Constructs this instance for the specified command encoder. */
|
MVKPipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {}
|
||||||
MVKPipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder)
|
|
||||||
: MVKCommandEncoderState(cmdEncoder) {}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void encodeImpl(uint32_t stage) override;
|
void encodeImpl(uint32_t stage) override;
|
||||||
@ -131,58 +137,38 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKViewportCommandEncoderState
|
#pragma mark MVKGraphicsPipelineCommandEncoderState
|
||||||
|
|
||||||
/** Holds encoder state established by viewport commands. */
|
/** Holds encoder state established by graphics pipeline commands. */
|
||||||
class MVKViewportCommandEncoderState : public MVKCommandEncoderState {
|
class MVKGraphicsPipelineCommandEncoderState : public MVKPipelineCommandEncoderState {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void bindPipeline(MVKPipeline* pipeline) override;
|
||||||
|
|
||||||
/**
|
MVKGraphicsPipeline* getGraphicsPipeline() { return (MVKGraphicsPipeline*)getPipeline(); }
|
||||||
* Sets one or more of the viewports, starting at the first index.
|
|
||||||
* The isSettingDynamically indicates that the scissor is being changed dynamically,
|
|
||||||
* which is only allowed if the pipeline was created as VK_DYNAMIC_STATE_SCISSOR.
|
|
||||||
*/
|
|
||||||
void setViewports(MVKArrayRef<const VkViewport> viewports,
|
|
||||||
uint32_t firstViewport,
|
|
||||||
bool isSettingDynamically);
|
|
||||||
|
|
||||||
/** Constructs this instance for the specified command encoder. */
|
void setPatchControlPoints(uint32_t patchControlPoints);
|
||||||
MVKViewportCommandEncoderState(MVKCommandEncoder* cmdEncoder)
|
uint32_t getPatchControlPoints();
|
||||||
: MVKCommandEncoderState(cmdEncoder) {}
|
|
||||||
|
MVKGraphicsPipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKPipelineCommandEncoderState(cmdEncoder) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void encodeImpl(uint32_t stage) override;
|
uint32_t _patchControlPoints[StateScope::Count] = {};
|
||||||
|
|
||||||
MVKSmallVector<VkViewport, kMVKMaxViewportScissorCount> _viewports, _dynamicViewports;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKScissorCommandEncoderState
|
#pragma mark MVKComputePipelineCommandEncoderState
|
||||||
|
|
||||||
/** Holds encoder state established by viewport commands. */
|
/** Holds encoder state established by compute pipeline commands. */
|
||||||
class MVKScissorCommandEncoderState : public MVKCommandEncoderState {
|
class MVKComputePipelineCommandEncoderState : public MVKPipelineCommandEncoderState {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
MVKComputePipeline* getComputePipeline() { return (MVKComputePipeline*)getPipeline(); }
|
||||||
|
|
||||||
/**
|
MVKComputePipelineCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKPipelineCommandEncoderState(cmdEncoder) {}
|
||||||
* Sets one or more of the scissors, starting at the first index.
|
|
||||||
* The isSettingDynamically indicates that the scissor is being changed dynamically,
|
|
||||||
* which is only allowed if the pipeline was created as VK_DYNAMIC_STATE_SCISSOR.
|
|
||||||
*/
|
|
||||||
void setScissors(MVKArrayRef<const VkRect2D> scissors,
|
|
||||||
uint32_t firstScissor,
|
|
||||||
bool isSettingDynamically);
|
|
||||||
|
|
||||||
/** Constructs this instance for the specified command encoder. */
|
|
||||||
MVKScissorCommandEncoderState(MVKCommandEncoder* cmdEncoder)
|
|
||||||
: MVKCommandEncoderState(cmdEncoder) {}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void encodeImpl(uint32_t stage) override;
|
|
||||||
|
|
||||||
MVKSmallVector<VkRect2D, kMVKMaxViewportScissorCount> _scissors, _dynamicScissors;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -226,16 +212,29 @@ public:
|
|||||||
/** Sets the depth stencil state during pipeline binding. */
|
/** Sets the depth stencil state during pipeline binding. */
|
||||||
void setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo);
|
void setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo);
|
||||||
|
|
||||||
/**
|
/** Enables or disables depth testing, from explicit dynamic command. */
|
||||||
* Sets the stencil compare mask value of the indicated faces
|
void setDepthTestEnable(VkBool32 depthTestEnable);
|
||||||
* to the specified value, from explicit dynamic command.
|
|
||||||
*/
|
/** Enables or disables depth writing, from explicit dynamic command. */
|
||||||
|
void setDepthWriteEnable(VkBool32 depthWriteEnable);
|
||||||
|
|
||||||
|
/** Sets the depth compare operation, from explicit dynamic command. */
|
||||||
|
void setDepthCompareOp(VkCompareOp depthCompareOp);
|
||||||
|
|
||||||
|
/** Enables or disables stencil testing, from explicit dynamic command. */
|
||||||
|
void setStencilTestEnable(VkBool32 stencilTestEnable);
|
||||||
|
|
||||||
|
/** Sets the stencil operations of the indicated faces from explicit dynamic command. */
|
||||||
|
void setStencilOp(VkStencilFaceFlags faceMask,
|
||||||
|
VkStencilOp failOp,
|
||||||
|
VkStencilOp passOp,
|
||||||
|
VkStencilOp depthFailOp,
|
||||||
|
VkCompareOp compareOp);
|
||||||
|
|
||||||
|
/** Sets the stencil compare mask value of the indicated faces from explicit dynamic command. */
|
||||||
void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t stencilCompareMask);
|
void setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t stencilCompareMask);
|
||||||
|
|
||||||
/**
|
/** Sets the stencil write mask value of the indicated faces from explicit dynamic command. */
|
||||||
* Sets the stencil write mask value of the indicated faces
|
|
||||||
* to the specified value, from explicit dynamic command.
|
|
||||||
*/
|
|
||||||
void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t stencilWriteMask);
|
void setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t stencilWriteMask);
|
||||||
|
|
||||||
void beginMetalRenderPass() override;
|
void beginMetalRenderPass() override;
|
||||||
@ -246,96 +245,108 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void encodeImpl(uint32_t stage) override;
|
void encodeImpl(uint32_t stage) override;
|
||||||
void setStencilState(MVKMTLStencilDescriptorData& stencilInfo,
|
MVKMTLDepthStencilDescriptorData& getData(MVKRenderStateType state) { return getContent(_depthStencilData, state); }
|
||||||
const VkStencilOpState& vkStencil,
|
template <typename T> void setContent(T& content, T value) {
|
||||||
bool enabled);
|
if (content != value) {
|
||||||
|
content = value;
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void setStencilState(MVKMTLStencilDescriptorData& sData, const VkStencilOpState& vkStencil);
|
||||||
|
void setStencilOp(MVKMTLStencilDescriptorData& sData, VkStencilOp failOp,
|
||||||
|
VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp);
|
||||||
|
|
||||||
MVKMTLDepthStencilDescriptorData _depthStencilData = kMVKMTLDepthStencilDescriptorDataDefault;
|
MVKMTLDepthStencilDescriptorData _depthStencilData[StateScope::Count];
|
||||||
|
bool _depthTestEnabled[StateScope::Count];
|
||||||
bool _hasDepthAttachment = false;
|
bool _hasDepthAttachment = false;
|
||||||
bool _hasStencilAttachment = false;
|
bool _hasStencilAttachment = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKStencilReferenceValueCommandEncoderState
|
#pragma mark MVKRenderingCommandEncoderState
|
||||||
|
|
||||||
/** Holds encoder state established by stencil reference values commands. */
|
struct MVKDepthBias {
|
||||||
class MVKStencilReferenceValueCommandEncoderState : public MVKCommandEncoderState {
|
float depthBiasConstantFactor;
|
||||||
|
float depthBiasSlopeFactor;
|
||||||
public:
|
float depthBiasClamp;
|
||||||
|
|
||||||
/** Sets the stencil references during pipeline binding. */
|
|
||||||
void setReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo);
|
|
||||||
|
|
||||||
/** Sets the stencil state from explicit dynamic command. */
|
|
||||||
void setReferenceValues(VkStencilFaceFlags faceMask, uint32_t stencilReference);
|
|
||||||
|
|
||||||
/** Constructs this instance for the specified command encoder. */
|
|
||||||
MVKStencilReferenceValueCommandEncoderState(MVKCommandEncoder* cmdEncoder)
|
|
||||||
: MVKCommandEncoderState(cmdEncoder) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void encodeImpl(uint32_t stage) override;
|
|
||||||
|
|
||||||
uint32_t _frontFaceValue = 0;
|
|
||||||
uint32_t _backFaceValue = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MVKStencilReference {
|
||||||
|
uint32_t frontFaceValue;
|
||||||
|
uint32_t backFaceValue;
|
||||||
|
};
|
||||||
|
|
||||||
#pragma mark -
|
struct MVKMTLViewports {
|
||||||
#pragma mark MVKDepthBiasCommandEncoderState
|
MTLViewport viewports[kMVKMaxViewportScissorCount];
|
||||||
|
uint32_t viewportCount;
|
||||||
|
};
|
||||||
|
|
||||||
/** Holds encoder state established by depth bias commands. */
|
struct MVKMTLScissors {
|
||||||
class MVKDepthBiasCommandEncoderState : public MVKCommandEncoderState {
|
MTLScissorRect scissors[kMVKMaxViewportScissorCount];
|
||||||
|
uint32_t scissorCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Holds encoder state established by various rendering state commands. */
|
||||||
|
class MVKRenderingCommandEncoderState : public MVKCommandEncoderState {
|
||||||
public:
|
public:
|
||||||
|
void setCullMode(VkCullModeFlags cullMode, bool isDynamic);
|
||||||
|
|
||||||
|
void setFrontFace(VkFrontFace frontFace, bool isDynamic);
|
||||||
|
|
||||||
|
void setPrimitiveTopology(VkPrimitiveTopology topology, bool isDynamic);
|
||||||
|
MTLPrimitiveType getPrimitiveType();
|
||||||
|
|
||||||
|
void setPolygonMode(VkPolygonMode polygonMode, bool isDynamic);
|
||||||
|
|
||||||
|
void setBlendConstants(float blendConstants[4], bool isDynamic);
|
||||||
|
|
||||||
/** Sets the depth bias during pipeline binding. */
|
|
||||||
void setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo);
|
void setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo);
|
||||||
|
void setDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor, float depthBiasClamp);
|
||||||
|
void setDepthBiasEnable(VkBool32 depthBiasEnable);
|
||||||
|
void setDepthClipEnable(bool depthClip, bool isDynamic);
|
||||||
|
|
||||||
/** Sets the depth bias dynamically. */
|
void setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo);
|
||||||
void setDepthBias(float depthBiasConstantFactor,
|
void setStencilReferenceValues(VkStencilFaceFlags faceMask, uint32_t stencilReference);
|
||||||
float depthBiasSlopeFactor,
|
|
||||||
float depthBiasClamp);
|
|
||||||
|
|
||||||
/** Constructs this instance for the specified command encoder. */
|
void setViewports(const MVKArrayRef<VkViewport> viewports, uint32_t firstViewport, bool isDynamic);
|
||||||
MVKDepthBiasCommandEncoderState(MVKCommandEncoder* cmdEncoder)
|
void setScissors(const MVKArrayRef<VkRect2D> scissors, uint32_t firstScissor, bool isDynamic);
|
||||||
: MVKCommandEncoderState(cmdEncoder) {}
|
|
||||||
|
void setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable, bool isDynamic);
|
||||||
|
|
||||||
|
void beginMetalRenderPass() override;
|
||||||
|
|
||||||
|
MVKRenderingCommandEncoderState(MVKCommandEncoder* cmdEncoder) : MVKCommandEncoderState(cmdEncoder) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void encodeImpl(uint32_t stage) override;
|
void encodeImpl(uint32_t stage) override;
|
||||||
|
bool isDirty(MVKRenderStateType state);
|
||||||
|
bool isDrawingTriangles();
|
||||||
|
template <typename T> void setContent(T* iVarAry, T* pVal, MVKRenderStateType state, bool isDynamic) {
|
||||||
|
auto* pIVar = &iVarAry[isDynamic ? StateScope::Dynamic : StateScope::Static];
|
||||||
|
if( !mvkAreEqual(pVal, pIVar) ) {
|
||||||
|
*pIVar = *pVal;
|
||||||
|
_dirtyStates.enable(state);
|
||||||
|
_modifiedStates.enable(state);
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float _depthBiasConstantFactor = 0;
|
MVKMTLViewports _mtlViewports[StateScope::Count] = {};
|
||||||
float _depthBiasClamp = 0;
|
MVKMTLScissors _mtlScissors[StateScope::Count] = {};
|
||||||
float _depthBiasSlopeFactor = 0;
|
MVKColor32 _mtlBlendConstants[StateScope::Count] = {};
|
||||||
bool _isEnabled = false;
|
MVKDepthBias _mtlDepthBias[StateScope::Count] = {};
|
||||||
};
|
MVKStencilReference _mtlStencilReference[StateScope::Count] = {};
|
||||||
|
MTLCullMode _mtlCullMode[StateScope::Count] = { MTLCullModeNone, MTLCullModeNone };
|
||||||
|
MTLWinding _mtlFrontFace[StateScope::Count] = { MTLWindingClockwise, MTLWindingClockwise };
|
||||||
#pragma mark -
|
MTLPrimitiveType _mtlPrimitiveTopology[StateScope::Count] = { MTLPrimitiveTypePoint, MTLPrimitiveTypePoint };
|
||||||
#pragma mark MVKBlendColorCommandEncoderState
|
MTLDepthClipMode _mtlDepthClipEnable[StateScope::Count] = { MTLDepthClipModeClip, MTLDepthClipModeClip };
|
||||||
|
MTLTriangleFillMode _mtlPolygonMode[StateScope::Count] = { MTLTriangleFillModeFill, MTLTriangleFillModeFill };
|
||||||
/** Holds encoder state established by blend color commands. */
|
MVKRenderStateFlags _dirtyStates;
|
||||||
class MVKBlendColorCommandEncoderState : public MVKCommandEncoderState {
|
MVKRenderStateFlags _modifiedStates;
|
||||||
|
bool _mtlDepthBiasEnable[StateScope::Count] = {};
|
||||||
public:
|
bool _mtlRasterizerDiscardEnable[StateScope::Count] = {};
|
||||||
|
bool _cullBothFaces[StateScope::Count] = {};
|
||||||
/** Sets the blend color, either as part of pipeline binding, or dynamically. */
|
|
||||||
void setBlendColor(float red, float green,
|
|
||||||
float blue, float alpha,
|
|
||||||
bool isDynamic);
|
|
||||||
|
|
||||||
/** Constructs this instance for the specified command encoder. */
|
|
||||||
MVKBlendColorCommandEncoderState(MVKCommandEncoder* cmdEncoder)
|
|
||||||
: MVKCommandEncoderState(cmdEncoder) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void encodeImpl(uint32_t stage) override;
|
|
||||||
|
|
||||||
float _red = 0;
|
|
||||||
float _green = 0;
|
|
||||||
float _blue = 0;
|
|
||||||
float _alpha = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,13 +25,21 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#define shouldUpdateFace(face) mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_##face##_BIT)
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKCommandEncoderState
|
#pragma mark MVKCommandEncoderState
|
||||||
|
|
||||||
MVKVulkanAPIObject* MVKCommandEncoderState::getVulkanAPIObject() { return _cmdEncoder->getVulkanAPIObject(); };
|
MVKVulkanAPIObject* MVKCommandEncoderState::getVulkanAPIObject() { return _cmdEncoder->getVulkanAPIObject(); };
|
||||||
|
|
||||||
MVKDevice* MVKCommandEncoderState::getDevice() { return _cmdEncoder->getDevice(); }
|
MVKDevice* MVKCommandEncoderState::getDevice() { return _cmdEncoder->getDevice(); }
|
||||||
|
|
||||||
|
bool MVKCommandEncoderState::isDynamicState(MVKRenderStateType state) {
|
||||||
|
auto* gpl = _cmdEncoder->_graphicsPipelineState.getGraphicsPipeline();
|
||||||
|
return !gpl || gpl->isDynamicState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKPipelineCommandEncoderState
|
#pragma mark MVKPipelineCommandEncoderState
|
||||||
@ -52,108 +60,19 @@ void MVKPipelineCommandEncoderState::encodeImpl(uint32_t stage) {
|
|||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKViewportCommandEncoderState
|
#pragma mark MVKGraphicsPipelineCommandEncoderState
|
||||||
|
|
||||||
void MVKViewportCommandEncoderState::setViewports(MVKArrayRef<const VkViewport> viewports,
|
void MVKGraphicsPipelineCommandEncoderState::bindPipeline(MVKPipeline* pipeline) {
|
||||||
uint32_t firstViewport,
|
MVKPipelineCommandEncoderState::bindPipeline(pipeline);
|
||||||
bool isSettingDynamically) {
|
_patchControlPoints[StateScope::Static] = getGraphicsPipeline()->_tessInfo.patchControlPoints;
|
||||||
|
|
||||||
size_t vpCnt = viewports.size();
|
|
||||||
uint32_t maxViewports = getDevice()->_pProperties->limits.maxViewports;
|
|
||||||
if ((firstViewport + vpCnt > maxViewports) ||
|
|
||||||
(firstViewport >= maxViewports) ||
|
|
||||||
(isSettingDynamically && vpCnt == 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto& usingViewports = isSettingDynamically ? _dynamicViewports : _viewports;
|
|
||||||
|
|
||||||
if (firstViewport + vpCnt > usingViewports.size()) {
|
|
||||||
usingViewports.resize(firstViewport + vpCnt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dirty;
|
void MVKGraphicsPipelineCommandEncoderState::setPatchControlPoints(uint32_t patchControlPoints) {
|
||||||
bool mustSetDynamically = _cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
|
_patchControlPoints[StateScope::Dynamic] = patchControlPoints;
|
||||||
if (isSettingDynamically || (!mustSetDynamically && vpCnt > 0)) {
|
|
||||||
dirty = memcmp(&usingViewports[firstViewport], &viewports[0], vpCnt * sizeof(VkViewport)) != 0;
|
|
||||||
std::copy(viewports.begin(), viewports.end(), usingViewports.begin() + firstViewport);
|
|
||||||
} else {
|
|
||||||
dirty = !usingViewports.empty();
|
|
||||||
usingViewports.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty) markDirty();
|
uint32_t MVKGraphicsPipelineCommandEncoderState::getPatchControlPoints() {
|
||||||
}
|
return getContent(_patchControlPoints, PatchControlPoints);
|
||||||
|
|
||||||
void MVKViewportCommandEncoderState::encodeImpl(uint32_t stage) {
|
|
||||||
if (stage != kMVKGraphicsStageRasterization) { return; }
|
|
||||||
auto& usingViewports = _viewports.size() > 0 ? _viewports : _dynamicViewports;
|
|
||||||
if (usingViewports.empty()) { return; }
|
|
||||||
|
|
||||||
if (_cmdEncoder->_pDeviceFeatures->multiViewport) {
|
|
||||||
size_t vpCnt = usingViewports.size();
|
|
||||||
MTLViewport mtlViewports[vpCnt];
|
|
||||||
for (uint32_t vpIdx = 0; vpIdx < vpCnt; vpIdx++) {
|
|
||||||
mtlViewports[vpIdx] = mvkMTLViewportFromVkViewport(usingViewports[vpIdx]);
|
|
||||||
}
|
|
||||||
#if MVK_MACOS_OR_IOS
|
|
||||||
[_cmdEncoder->_mtlRenderEncoder setViewports: mtlViewports count: vpCnt];
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
[_cmdEncoder->_mtlRenderEncoder setViewport: mvkMTLViewportFromVkViewport(usingViewports[0])];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark MVKScissorCommandEncoderState
|
|
||||||
|
|
||||||
void MVKScissorCommandEncoderState::setScissors(MVKArrayRef<const VkRect2D> scissors,
|
|
||||||
uint32_t firstScissor,
|
|
||||||
bool isSettingDynamically) {
|
|
||||||
|
|
||||||
size_t sCnt = scissors.size();
|
|
||||||
uint32_t maxScissors = getDevice()->_pProperties->limits.maxViewports;
|
|
||||||
if ((firstScissor + sCnt > maxScissors) ||
|
|
||||||
(firstScissor >= maxScissors) ||
|
|
||||||
(isSettingDynamically && sCnt == 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto& usingScissors = isSettingDynamically ? _dynamicScissors : _scissors;
|
|
||||||
|
|
||||||
if (firstScissor + sCnt > usingScissors.size()) {
|
|
||||||
usingScissors.resize(firstScissor + sCnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool dirty;
|
|
||||||
bool mustSetDynamically = _cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_SCISSOR);
|
|
||||||
if (isSettingDynamically || (!mustSetDynamically && sCnt > 0)) {
|
|
||||||
dirty = memcmp(&usingScissors[firstScissor], &scissors[0], sCnt * sizeof(VkRect2D)) != 0;
|
|
||||||
std::copy(scissors.begin(), scissors.end(), usingScissors.begin() + firstScissor);
|
|
||||||
} else {
|
|
||||||
dirty = !usingScissors.empty();
|
|
||||||
usingScissors.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dirty) markDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MVKScissorCommandEncoderState::encodeImpl(uint32_t stage) {
|
|
||||||
if (stage != kMVKGraphicsStageRasterization) { return; }
|
|
||||||
auto& usingScissors = _scissors.size() > 0 ? _scissors : _dynamicScissors;
|
|
||||||
if (usingScissors.empty()) { return; }
|
|
||||||
|
|
||||||
if (_cmdEncoder->_pDeviceFeatures->multiViewport) {
|
|
||||||
size_t sCnt = usingScissors.size();
|
|
||||||
MTLScissorRect mtlScissors[sCnt];
|
|
||||||
for (uint32_t sIdx = 0; sIdx < sCnt; sIdx++) {
|
|
||||||
mtlScissors[sIdx] = mvkMTLScissorRectFromVkRect2D(_cmdEncoder->clipToRenderArea(usingScissors[sIdx]));
|
|
||||||
}
|
|
||||||
#if MVK_MACOS_OR_IOS
|
|
||||||
[_cmdEncoder->_mtlRenderEncoder setScissorRects: mtlScissors count: sCnt];
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
[_cmdEncoder->_mtlRenderEncoder setScissorRect: mvkMTLScissorRectFromVkRect2D(_cmdEncoder->clipToRenderArea(usingScissors[0]))];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -245,7 +164,7 @@ void MVKPushConstantsCommandEncoderState::encodeImpl(uint32_t stage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MVKPushConstantsCommandEncoderState::isTessellating() {
|
bool MVKPushConstantsCommandEncoderState::isTessellating() {
|
||||||
MVKGraphicsPipeline* gp = (MVKGraphicsPipeline*)_cmdEncoder->_graphicsPipelineState.getPipeline();
|
auto* gp = _cmdEncoder->_graphicsPipelineState.getGraphicsPipeline();
|
||||||
return gp ? gp->isTessellationPipeline() : false;
|
return gp ? gp->isTessellationPipeline() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,74 +173,84 @@ bool MVKPushConstantsCommandEncoderState::isTessellating() {
|
|||||||
#pragma mark MVKDepthStencilCommandEncoderState
|
#pragma mark MVKDepthStencilCommandEncoderState
|
||||||
|
|
||||||
void MVKDepthStencilCommandEncoderState:: setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) {
|
void MVKDepthStencilCommandEncoderState:: setDepthStencilState(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) {
|
||||||
auto oldData = _depthStencilData;
|
auto& depthEnabled = _depthTestEnabled[StateScope::Static];
|
||||||
|
auto oldDepthEnabled = depthEnabled;
|
||||||
|
depthEnabled = static_cast<bool>(vkDepthStencilInfo.depthTestEnable);
|
||||||
|
|
||||||
if (vkDepthStencilInfo.depthTestEnable) {
|
auto& dsData = _depthStencilData[StateScope::Static];
|
||||||
_depthStencilData.depthCompareFunction = mvkMTLCompareFunctionFromVkCompareOp(vkDepthStencilInfo.depthCompareOp);
|
auto oldData = dsData;
|
||||||
_depthStencilData.depthWriteEnabled = vkDepthStencilInfo.depthWriteEnable;
|
dsData.depthCompareFunction = mvkMTLCompareFunctionFromVkCompareOp(vkDepthStencilInfo.depthCompareOp);
|
||||||
} else {
|
dsData.depthWriteEnabled = vkDepthStencilInfo.depthWriteEnable;
|
||||||
_depthStencilData.depthCompareFunction = kMVKMTLDepthStencilDescriptorDataDefault.depthCompareFunction;
|
|
||||||
_depthStencilData.depthWriteEnabled = kMVKMTLDepthStencilDescriptorDataDefault.depthWriteEnabled;
|
dsData.stencilTestEnabled = static_cast<bool>(vkDepthStencilInfo.stencilTestEnable);
|
||||||
|
setStencilState(dsData.frontFaceStencilData, vkDepthStencilInfo.front);
|
||||||
|
setStencilState(dsData.backFaceStencilData, vkDepthStencilInfo.back);
|
||||||
|
|
||||||
|
if (depthEnabled != oldDepthEnabled || dsData != oldData) { markDirty(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
setStencilState(_depthStencilData.frontFaceStencilData, vkDepthStencilInfo.front, vkDepthStencilInfo.stencilTestEnable);
|
void MVKDepthStencilCommandEncoderState::setStencilState(MVKMTLStencilDescriptorData& sData,
|
||||||
setStencilState(_depthStencilData.backFaceStencilData, vkDepthStencilInfo.back, vkDepthStencilInfo.stencilTestEnable);
|
const VkStencilOpState& vkStencil) {
|
||||||
|
sData.readMask = vkStencil.compareMask;
|
||||||
if (!(oldData == _depthStencilData)) markDirty();
|
sData.writeMask = vkStencil.writeMask;
|
||||||
|
sData.stencilCompareFunction = mvkMTLCompareFunctionFromVkCompareOp(vkStencil.compareOp);
|
||||||
|
sData.stencilFailureOperation = mvkMTLStencilOperationFromVkStencilOp(vkStencil.failOp);
|
||||||
|
sData.depthFailureOperation = mvkMTLStencilOperationFromVkStencilOp(vkStencil.depthFailOp);
|
||||||
|
sData.depthStencilPassOperation = mvkMTLStencilOperationFromVkStencilOp(vkStencil.passOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKDepthStencilCommandEncoderState::setStencilState(MVKMTLStencilDescriptorData& stencilInfo,
|
void MVKDepthStencilCommandEncoderState::setDepthTestEnable(VkBool32 depthTestEnable) {
|
||||||
const VkStencilOpState& vkStencil,
|
setContent(_depthTestEnabled[StateScope::Dynamic], static_cast<bool>(depthTestEnable));
|
||||||
bool enabled) {
|
|
||||||
if ( !enabled ) {
|
|
||||||
stencilInfo = kMVKMTLStencilDescriptorDataDefault;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stencilInfo.enabled = true;
|
void MVKDepthStencilCommandEncoderState::setDepthWriteEnable(VkBool32 depthWriteEnable) {
|
||||||
stencilInfo.stencilCompareFunction = mvkMTLCompareFunctionFromVkCompareOp(vkStencil.compareOp);
|
setContent(_depthStencilData[StateScope::Dynamic].depthWriteEnabled, static_cast<bool>(depthWriteEnable));
|
||||||
stencilInfo.stencilFailureOperation = mvkMTLStencilOperationFromVkStencilOp(vkStencil.failOp);
|
}
|
||||||
stencilInfo.depthFailureOperation = mvkMTLStencilOperationFromVkStencilOp(vkStencil.depthFailOp);
|
|
||||||
stencilInfo.depthStencilPassOperation = mvkMTLStencilOperationFromVkStencilOp(vkStencil.passOp);
|
void MVKDepthStencilCommandEncoderState::setDepthCompareOp(VkCompareOp depthCompareOp) {
|
||||||
|
setContent(_depthStencilData[StateScope::Dynamic].depthCompareFunction,
|
||||||
if ( !_cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) ) {
|
(uint8_t)mvkMTLCompareFunctionFromVkCompareOp(depthCompareOp));
|
||||||
stencilInfo.readMask = vkStencil.compareMask;
|
}
|
||||||
}
|
|
||||||
if ( !_cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK) ) {
|
void MVKDepthStencilCommandEncoderState::setStencilTestEnable(VkBool32 stencilTestEnable) {
|
||||||
stencilInfo.writeMask = vkStencil.writeMask;
|
setContent(_depthStencilData[StateScope::Dynamic].stencilTestEnabled, static_cast<bool>(stencilTestEnable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MVKDepthStencilCommandEncoderState::setStencilOp(MVKMTLStencilDescriptorData& sData,
|
||||||
|
VkStencilOp failOp,
|
||||||
|
VkStencilOp passOp,
|
||||||
|
VkStencilOp depthFailOp,
|
||||||
|
VkCompareOp compareOp) {
|
||||||
|
auto oldData = sData;
|
||||||
|
sData.stencilCompareFunction = mvkMTLCompareFunctionFromVkCompareOp(compareOp);
|
||||||
|
sData.stencilFailureOperation = mvkMTLStencilOperationFromVkStencilOp(failOp);
|
||||||
|
sData.depthFailureOperation = mvkMTLStencilOperationFromVkStencilOp(depthFailOp);
|
||||||
|
sData.depthStencilPassOperation = mvkMTLStencilOperationFromVkStencilOp(passOp);
|
||||||
|
if (sData != oldData) { markDirty(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKDepthStencilCommandEncoderState::setStencilOp(VkStencilFaceFlags faceMask,
|
||||||
|
VkStencilOp failOp,
|
||||||
|
VkStencilOp passOp,
|
||||||
|
VkStencilOp depthFailOp,
|
||||||
|
VkCompareOp compareOp) {
|
||||||
|
auto& dsData = _depthStencilData[StateScope::Dynamic];
|
||||||
|
if (shouldUpdateFace(FRONT)) { setStencilOp(dsData.frontFaceStencilData, failOp, passOp, depthFailOp, compareOp); }
|
||||||
|
if (shouldUpdateFace(BACK)) { setStencilOp(dsData.backFaceStencilData, failOp, passOp, depthFailOp, compareOp); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't check for dynamic state here, because if this is called before pipeline is set,
|
|
||||||
// it may not be accurate, and if not dynamic, pipeline will override when it is encoded anyway.
|
|
||||||
void MVKDepthStencilCommandEncoderState::setStencilCompareMask(VkStencilFaceFlags faceMask,
|
void MVKDepthStencilCommandEncoderState::setStencilCompareMask(VkStencilFaceFlags faceMask,
|
||||||
uint32_t stencilCompareMask) {
|
uint32_t stencilCompareMask) {
|
||||||
auto oldData = _depthStencilData;
|
auto& dsData = _depthStencilData[StateScope::Dynamic];
|
||||||
|
if (shouldUpdateFace(FRONT)) { setContent(dsData.frontFaceStencilData.readMask, stencilCompareMask); }
|
||||||
if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_FRONT_BIT)) {
|
if (shouldUpdateFace(BACK)) { setContent(dsData.backFaceStencilData.readMask, stencilCompareMask); }
|
||||||
_depthStencilData.frontFaceStencilData.readMask = stencilCompareMask;
|
|
||||||
}
|
|
||||||
if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_BACK_BIT)) {
|
|
||||||
_depthStencilData.backFaceStencilData.readMask = stencilCompareMask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(oldData == _depthStencilData)) markDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't check for dynamic state here, because if this is called before pipeline is set,
|
|
||||||
// it may not be accurate, and if not dynamic, pipeline will override when it is encoded anyway.
|
|
||||||
void MVKDepthStencilCommandEncoderState::setStencilWriteMask(VkStencilFaceFlags faceMask,
|
void MVKDepthStencilCommandEncoderState::setStencilWriteMask(VkStencilFaceFlags faceMask,
|
||||||
uint32_t stencilWriteMask) {
|
uint32_t stencilWriteMask) {
|
||||||
auto oldData = _depthStencilData;
|
auto& dsData = _depthStencilData[StateScope::Dynamic];
|
||||||
|
if (shouldUpdateFace(FRONT)) { setContent(dsData.frontFaceStencilData.writeMask, stencilWriteMask); }
|
||||||
if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_FRONT_BIT)) {
|
if (shouldUpdateFace(BACK)) { setContent(dsData.backFaceStencilData.writeMask, stencilWriteMask); }
|
||||||
_depthStencilData.frontFaceStencilData.writeMask = stencilWriteMask;
|
|
||||||
}
|
|
||||||
if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_BACK_BIT)) {
|
|
||||||
_depthStencilData.backFaceStencilData.writeMask = stencilWriteMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(oldData == _depthStencilData)) markDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKDepthStencilCommandEncoderState::beginMetalRenderPass() {
|
void MVKDepthStencilCommandEncoderState::beginMetalRenderPass() {
|
||||||
@ -337,130 +266,255 @@ void MVKDepthStencilCommandEncoderState::beginMetalRenderPass() {
|
|||||||
if (_hasStencilAttachment != prevHasStencilAttachment) { markDirty(); }
|
if (_hasStencilAttachment != prevHasStencilAttachment) { markDirty(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Combine static and dynamic depth/stencil data
|
||||||
void MVKDepthStencilCommandEncoderState::encodeImpl(uint32_t stage) {
|
void MVKDepthStencilCommandEncoderState::encodeImpl(uint32_t stage) {
|
||||||
auto cmdEncPool = _cmdEncoder->getCommandEncodingPool();
|
|
||||||
switch (stage) {
|
|
||||||
case kMVKGraphicsStageRasterization: {
|
|
||||||
// If renderpass does not have a depth or a stencil attachment, disable corresponding test
|
|
||||||
MVKMTLDepthStencilDescriptorData adjustedDSData = _depthStencilData;
|
|
||||||
adjustedDSData.disable(!_hasDepthAttachment, !_hasStencilAttachment);
|
|
||||||
[_cmdEncoder->_mtlRenderEncoder setDepthStencilState: cmdEncPool->getMTLDepthStencilState(adjustedDSData)];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: // Do nothing on other stages
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
|
||||||
#pragma mark MVKStencilReferenceValueCommandEncoderState
|
|
||||||
|
|
||||||
void MVKStencilReferenceValueCommandEncoderState:: setReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) {
|
|
||||||
|
|
||||||
// If ref values are to be set dynamically, don't set them here.
|
|
||||||
if (_cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE)) { return; }
|
|
||||||
|
|
||||||
if (_frontFaceValue != vkDepthStencilInfo.front.reference || _backFaceValue != vkDepthStencilInfo.back.reference)
|
|
||||||
markDirty();
|
|
||||||
|
|
||||||
_frontFaceValue = vkDepthStencilInfo.front.reference;
|
|
||||||
_backFaceValue = vkDepthStencilInfo.back.reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't check for dynamic state here, because if this is called before pipeline is set,
|
|
||||||
// it may not be accurate, and if not dynamic, pipeline will override when it is encoded anyway.
|
|
||||||
void MVKStencilReferenceValueCommandEncoderState::setReferenceValues(VkStencilFaceFlags faceMask,
|
|
||||||
uint32_t stencilReference) {
|
|
||||||
bool dirty = false;
|
|
||||||
if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_FRONT_BIT)) {
|
|
||||||
dirty |= (_frontFaceValue != stencilReference);
|
|
||||||
_frontFaceValue = stencilReference;
|
|
||||||
}
|
|
||||||
if (mvkAreAllFlagsEnabled(faceMask, VK_STENCIL_FACE_BACK_BIT)) {
|
|
||||||
dirty |= (_backFaceValue != stencilReference);
|
|
||||||
_backFaceValue = stencilReference;
|
|
||||||
}
|
|
||||||
if (dirty) markDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MVKStencilReferenceValueCommandEncoderState::encodeImpl(uint32_t stage) {
|
|
||||||
if (stage != kMVKGraphicsStageRasterization) { return; }
|
if (stage != kMVKGraphicsStageRasterization) { return; }
|
||||||
[_cmdEncoder->_mtlRenderEncoder setStencilFrontReferenceValue: _frontFaceValue
|
|
||||||
backReferenceValue: _backFaceValue];
|
MVKMTLDepthStencilDescriptorData dsData;
|
||||||
|
|
||||||
|
if (_hasDepthAttachment && getContent(_depthTestEnabled, DepthTestEnable)) {
|
||||||
|
dsData.depthCompareFunction = getData(DepthCompareOp).depthCompareFunction;
|
||||||
|
dsData.depthWriteEnabled = getData(DepthWriteEnable).depthWriteEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_hasStencilAttachment && getData(StencilTestEnable).stencilTestEnabled) {
|
||||||
|
dsData.stencilTestEnabled = true;
|
||||||
|
|
||||||
|
auto& frontFace = dsData.frontFaceStencilData;
|
||||||
|
auto& backFace = dsData.backFaceStencilData;
|
||||||
|
|
||||||
|
const auto& srcRM = getData(StencilCompareMask);
|
||||||
|
frontFace.readMask = srcRM.frontFaceStencilData.readMask;
|
||||||
|
backFace.readMask = srcRM.backFaceStencilData.readMask;
|
||||||
|
|
||||||
|
const auto& srcWM = getData(StencilWriteMask);
|
||||||
|
frontFace.writeMask = srcWM.frontFaceStencilData.writeMask;
|
||||||
|
backFace.writeMask = srcWM.backFaceStencilData.writeMask;
|
||||||
|
|
||||||
|
const auto& srcSOp = getData(StencilOp);
|
||||||
|
frontFace.stencilCompareFunction = srcSOp.frontFaceStencilData.stencilCompareFunction;
|
||||||
|
frontFace.stencilFailureOperation = srcSOp.frontFaceStencilData.stencilFailureOperation;
|
||||||
|
frontFace.depthFailureOperation = srcSOp.frontFaceStencilData.depthFailureOperation;
|
||||||
|
frontFace.depthStencilPassOperation = srcSOp.frontFaceStencilData.depthStencilPassOperation;
|
||||||
|
|
||||||
|
backFace.stencilCompareFunction = srcSOp.backFaceStencilData.stencilCompareFunction;
|
||||||
|
backFace.stencilFailureOperation = srcSOp.backFaceStencilData.stencilFailureOperation;
|
||||||
|
backFace.depthFailureOperation = srcSOp.backFaceStencilData.depthFailureOperation;
|
||||||
|
backFace.depthStencilPassOperation = srcSOp.backFaceStencilData.depthStencilPassOperation;
|
||||||
|
}
|
||||||
|
|
||||||
|
[_cmdEncoder->_mtlRenderEncoder setDepthStencilState: _cmdEncoder->getCommandEncodingPool()->getMTLDepthStencilState(dsData)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark MVKDepthBiasCommandEncoderState
|
#pragma mark MVKRenderingCommandEncoderState
|
||||||
|
|
||||||
void MVKDepthBiasCommandEncoderState::setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo) {
|
#define getContent(state) getContent(_mtl##state, state)
|
||||||
|
#define setContent(state) setContent(_mtl##state, &mtl##state, state, isDynamic)
|
||||||
|
|
||||||
auto wasEnabled = _isEnabled;
|
void MVKRenderingCommandEncoderState::setCullMode(VkCullModeFlags cullMode, bool isDynamic) {
|
||||||
_isEnabled = vkRasterInfo.depthBiasEnable;
|
auto mtlCullMode = mvkMTLCullModeFromVkCullModeFlags(cullMode);
|
||||||
|
setContent(CullMode);
|
||||||
|
_cullBothFaces[isDynamic ? StateScope::Dynamic : StateScope::Static] = (cullMode == VK_CULL_MODE_FRONT_AND_BACK);
|
||||||
|
}
|
||||||
|
|
||||||
// If ref values are to be set dynamically, don't set them here.
|
void MVKRenderingCommandEncoderState::setFrontFace(VkFrontFace frontFace, bool isDynamic) {
|
||||||
if (_cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS)) { return; }
|
auto mtlFrontFace = mvkMTLWindingFromVkFrontFace(frontFace);
|
||||||
|
setContent(FrontFace);
|
||||||
|
}
|
||||||
|
|
||||||
if (_isEnabled != wasEnabled || _depthBiasConstantFactor != vkRasterInfo.depthBiasConstantFactor
|
void MVKRenderingCommandEncoderState::setPrimitiveTopology(VkPrimitiveTopology topology, bool isDynamic) {
|
||||||
|| _depthBiasSlopeFactor != vkRasterInfo.depthBiasSlopeFactor || _depthBiasClamp != vkRasterInfo.depthBiasClamp) {
|
auto mtlPrimitiveTopology = mvkMTLPrimitiveTypeFromVkPrimitiveTopology(topology);
|
||||||
|
setContent(PrimitiveTopology);
|
||||||
|
}
|
||||||
|
|
||||||
markDirty();
|
MTLPrimitiveType MVKRenderingCommandEncoderState::getPrimitiveType() {
|
||||||
_depthBiasConstantFactor = vkRasterInfo.depthBiasConstantFactor;
|
return getContent(PrimitiveTopology);
|
||||||
_depthBiasSlopeFactor = vkRasterInfo.depthBiasSlopeFactor;
|
}
|
||||||
_depthBiasClamp = vkRasterInfo.depthBiasClamp;
|
|
||||||
|
bool MVKRenderingCommandEncoderState::isDrawingTriangles() {
|
||||||
|
switch (getPrimitiveType()) {
|
||||||
|
case MTLPrimitiveTypeTriangle: return true;
|
||||||
|
case MTLPrimitiveTypeTriangleStrip: return true;
|
||||||
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't check for dynamic state here, because if this is called before pipeline is set,
|
void MVKRenderingCommandEncoderState::setPolygonMode(VkPolygonMode polygonMode, bool isDynamic) {
|
||||||
// it may not be accurate, and if not dynamic, pipeline will override when it is encoded anyway.
|
auto mtlPolygonMode = mvkMTLTriangleFillModeFromVkPolygonMode(polygonMode);
|
||||||
void MVKDepthBiasCommandEncoderState::setDepthBias(float depthBiasConstantFactor,
|
setContent(PolygonMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKRenderingCommandEncoderState::setBlendConstants(float blendConstants[4], bool isDynamic) {
|
||||||
|
MVKColor32 mtlBlendConstants;
|
||||||
|
mvkCopy(mtlBlendConstants.float32, blendConstants, 4);
|
||||||
|
setContent(BlendConstants);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKRenderingCommandEncoderState::setDepthBias(const VkPipelineRasterizationStateCreateInfo& vkRasterInfo) {
|
||||||
|
bool isDynamic = false;
|
||||||
|
|
||||||
|
bool mtlDepthBiasEnable = static_cast<bool>(vkRasterInfo.depthBiasEnable);
|
||||||
|
setContent(DepthBiasEnable);
|
||||||
|
|
||||||
|
MVKDepthBias mtlDepthBias = {
|
||||||
|
.depthBiasConstantFactor = vkRasterInfo.depthBiasConstantFactor,
|
||||||
|
.depthBiasSlopeFactor = vkRasterInfo.depthBiasSlopeFactor,
|
||||||
|
.depthBiasClamp = vkRasterInfo.depthBiasClamp
|
||||||
|
};
|
||||||
|
setContent(DepthBias);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKRenderingCommandEncoderState::setDepthBias(float depthBiasConstantFactor,
|
||||||
float depthBiasSlopeFactor,
|
float depthBiasSlopeFactor,
|
||||||
float depthBiasClamp) {
|
float depthBiasClamp) {
|
||||||
|
bool isDynamic = true;
|
||||||
if (_depthBiasConstantFactor != depthBiasConstantFactor || _depthBiasSlopeFactor != depthBiasSlopeFactor
|
MVKDepthBias mtlDepthBias = {
|
||||||
|| _depthBiasClamp != depthBiasClamp) {
|
.depthBiasConstantFactor = depthBiasConstantFactor,
|
||||||
|
.depthBiasSlopeFactor = depthBiasSlopeFactor,
|
||||||
markDirty();
|
.depthBiasClamp = depthBiasClamp
|
||||||
_depthBiasConstantFactor = depthBiasConstantFactor;
|
};
|
||||||
_depthBiasSlopeFactor = depthBiasSlopeFactor;
|
setContent(DepthBias);
|
||||||
_depthBiasClamp = depthBiasClamp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKDepthBiasCommandEncoderState::encodeImpl(uint32_t stage) {
|
void MVKRenderingCommandEncoderState::setDepthBiasEnable(VkBool32 depthBiasEnable) {
|
||||||
if (stage != kMVKGraphicsStageRasterization) { return; }
|
bool isDynamic = true;
|
||||||
if (_isEnabled) {
|
bool mtlDepthBiasEnable = static_cast<bool>(depthBiasEnable);
|
||||||
[_cmdEncoder->_mtlRenderEncoder setDepthBias: _depthBiasConstantFactor
|
setContent(DepthBiasEnable);
|
||||||
slopeScale: _depthBiasSlopeFactor
|
|
||||||
clamp: _depthBiasClamp];
|
|
||||||
} else {
|
|
||||||
[_cmdEncoder->_mtlRenderEncoder setDepthBias: 0 slopeScale: 0 clamp: 0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MVKRenderingCommandEncoderState::setDepthClipEnable(bool depthClip, bool isDynamic) {
|
||||||
|
auto mtlDepthClipEnable = depthClip ? MTLDepthClipModeClip : MTLDepthClipModeClamp;
|
||||||
|
setContent(DepthClipEnable);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark -
|
void MVKRenderingCommandEncoderState::setStencilReferenceValues(const VkPipelineDepthStencilStateCreateInfo& vkDepthStencilInfo) {
|
||||||
#pragma mark MVKBlendColorCommandEncoderState
|
bool isDynamic = false;
|
||||||
|
MVKStencilReference mtlStencilReference = {
|
||||||
|
.frontFaceValue = vkDepthStencilInfo.front.reference,
|
||||||
|
.backFaceValue = vkDepthStencilInfo.back.reference
|
||||||
|
};
|
||||||
|
setContent(StencilReference);
|
||||||
|
}
|
||||||
|
|
||||||
void MVKBlendColorCommandEncoderState::setBlendColor(float red, float green,
|
void MVKRenderingCommandEncoderState::setStencilReferenceValues(VkStencilFaceFlags faceMask, uint32_t stencilReference) {
|
||||||
float blue, float alpha,
|
bool isDynamic = true;
|
||||||
|
MVKStencilReference mtlStencilReference = _mtlStencilReference[StateScope::Dynamic];
|
||||||
|
if (shouldUpdateFace(FRONT)) { mtlStencilReference.frontFaceValue = stencilReference; }
|
||||||
|
if (shouldUpdateFace(BACK)) { mtlStencilReference.backFaceValue = stencilReference; }
|
||||||
|
setContent(StencilReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKRenderingCommandEncoderState::setViewports(const MVKArrayRef<VkViewport> viewports,
|
||||||
|
uint32_t firstViewport,
|
||||||
bool isDynamic) {
|
bool isDynamic) {
|
||||||
// Abort if we are using dynamic, but call is not dynamic.
|
uint32_t maxViewports = getDevice()->_pProperties->limits.maxViewports;
|
||||||
if ( !isDynamic && _cmdEncoder->supportsDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS) ) { return; }
|
if (firstViewport >= maxViewports) { return; }
|
||||||
|
|
||||||
if (_red != red || _green != green || _blue != blue || _alpha != alpha) {
|
MVKMTLViewports mtlViewports = isDynamic ? _mtlViewports[StateScope::Dynamic] : _mtlViewports[StateScope::Static];
|
||||||
markDirty();
|
size_t vpCnt = min((uint32_t)viewports.size(), maxViewports - firstViewport);
|
||||||
_red = red;
|
for (uint32_t vpIdx = 0; vpIdx < vpCnt; vpIdx++) {
|
||||||
_green = green;
|
mtlViewports.viewports[firstViewport + vpIdx] = mvkMTLViewportFromVkViewport(viewports[vpIdx]);
|
||||||
_blue = blue;
|
mtlViewports.viewportCount = max(mtlViewports.viewportCount, vpIdx + 1);
|
||||||
_alpha = alpha;
|
|
||||||
}
|
}
|
||||||
|
setContent(Viewports);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MVKBlendColorCommandEncoderState::encodeImpl(uint32_t stage) {
|
void MVKRenderingCommandEncoderState::setScissors(const MVKArrayRef<VkRect2D> scissors,
|
||||||
|
uint32_t firstScissor,
|
||||||
|
bool isDynamic) {
|
||||||
|
uint32_t maxScissors = getDevice()->_pProperties->limits.maxViewports;
|
||||||
|
if (firstScissor >= maxScissors) { return; }
|
||||||
|
|
||||||
|
MVKMTLScissors mtlScissors = isDynamic ? _mtlScissors[StateScope::Dynamic] : _mtlScissors[StateScope::Static];
|
||||||
|
size_t sCnt = min((uint32_t)scissors.size(), maxScissors - firstScissor);
|
||||||
|
for (uint32_t sIdx = 0; sIdx < sCnt; sIdx++) {
|
||||||
|
mtlScissors.scissors[firstScissor + sIdx] = mvkMTLScissorRectFromVkRect2D(scissors[sIdx]);
|
||||||
|
mtlScissors.scissorCount = max(mtlScissors.scissorCount, sIdx + 1);
|
||||||
|
}
|
||||||
|
setContent(Scissors);
|
||||||
|
}
|
||||||
|
|
||||||
|
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; }
|
if (stage != kMVKGraphicsStageRasterization) { return; }
|
||||||
[_cmdEncoder->_mtlRenderEncoder setBlendColorRed: _red green: _green blue: _blue alpha: _alpha];
|
|
||||||
|
auto& rendEnc = _cmdEncoder->_mtlRenderEncoder;
|
||||||
|
|
||||||
|
if (isDirty(CullMode)) { [rendEnc setCullMode: getContent(CullMode)]; }
|
||||||
|
if (isDirty(FrontFace)) { [rendEnc setFrontFacingWinding: getContent(FrontFace)]; }
|
||||||
|
if (isDirty(BlendConstants)) {
|
||||||
|
auto& bcFlt = getContent(BlendConstants).float32;
|
||||||
|
[rendEnc setBlendColorRed: bcFlt[0] green: bcFlt[1] blue: bcFlt[2] alpha: bcFlt[3]];
|
||||||
|
}
|
||||||
|
if (isDirty(DepthBiasEnable) || isDirty(DepthBias)) {
|
||||||
|
if (getContent(DepthBiasEnable)) {
|
||||||
|
auto& db = getContent(DepthBias);
|
||||||
|
[rendEnc setDepthBias: db.depthBiasConstantFactor
|
||||||
|
slopeScale: db.depthBiasSlopeFactor
|
||||||
|
clamp: db.depthBiasClamp];
|
||||||
|
} else {
|
||||||
|
[rendEnc setDepthBias: 0 slopeScale: 0 clamp: 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isDirty(DepthClipEnable) && _cmdEncoder->_pDeviceFeatures->depthClamp) {
|
||||||
|
[rendEnc setDepthClipMode: getContent(DepthClipEnable)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDirty(StencilReference)) {
|
||||||
|
auto& sr = getContent(StencilReference);
|
||||||
|
[rendEnc setStencilFrontReferenceValue: sr.frontFaceValue backReferenceValue: sr.backFaceValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDirty(Viewports)) {
|
||||||
|
auto& mtlViewports = getContent(Viewports);
|
||||||
|
if (_cmdEncoder->_pDeviceFeatures->multiViewport) {
|
||||||
|
#if MVK_MACOS_OR_IOS
|
||||||
|
[rendEnc setViewports: mtlViewports.viewports count: mtlViewports.viewportCount];
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
[rendEnc setViewport: mtlViewports.viewports[0]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)) {
|
||||||
|
static MTLScissorRect zeroRect = {};
|
||||||
|
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] = shouldDiscard ? zeroRect : _cmdEncoder->clipToRenderArea(mtlScissors.scissors[sIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cmdEncoder->_pDeviceFeatures->multiViewport) {
|
||||||
|
#if MVK_MACOS_OR_IOS
|
||||||
|
[rendEnc setScissorRects: mtlScissors.scissors count: mtlScissors.scissorCount];
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
[rendEnc setScissorRect: mtlScissors.scissors[0]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return whether state is dirty, and mark it not dirty
|
||||||
|
bool MVKRenderingCommandEncoderState::isDirty(MVKRenderStateType state) {
|
||||||
|
bool rslt = _dirtyStates.isEnabled(state);
|
||||||
|
_dirtyStates.disable(state);
|
||||||
|
return rslt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MVKRenderingCommandEncoderState::beginMetalRenderPass() {
|
||||||
|
MVKCommandEncoderState::beginMetalRenderPass();
|
||||||
|
_dirtyStates = _modifiedStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -772,11 +826,16 @@ void MVKGraphicsResourcesCommandEncoderState::markDirty() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !MVK_XCODE_15
|
||||||
|
static const NSUInteger MTLAttributeStrideStatic = NSUIntegerMax;
|
||||||
|
#endif
|
||||||
|
|
||||||
void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
|
void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
|
||||||
|
|
||||||
MVKGraphicsPipeline* pipeline = (MVKGraphicsPipeline*)getPipeline();
|
auto* pipeline = _cmdEncoder->_graphicsPipelineState.getGraphicsPipeline();
|
||||||
bool fullImageViewSwizzle = pipeline->fullImageViewSwizzle() || getDevice()->_pMetalFeatures->nativeTextureSwizzle;
|
bool fullImageViewSwizzle = pipeline->fullImageViewSwizzle() || getDevice()->_pMetalFeatures->nativeTextureSwizzle;
|
||||||
bool forTessellation = pipeline->isTessellationPipeline();
|
bool forTessellation = pipeline->isTessellationPipeline();
|
||||||
|
bool isDynamicVertexStride = pipeline->isDynamicState(VertexStride);
|
||||||
|
|
||||||
if (stage == kMVKGraphicsStageVertex) {
|
if (stage == kMVKGraphicsStageVertex) {
|
||||||
encodeBindings(kMVKShaderStageVertex, "vertex", fullImageViewSwizzle,
|
encodeBindings(kMVKShaderStageVertex, "vertex", fullImageViewSwizzle,
|
||||||
@ -812,33 +871,24 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
|
|||||||
|
|
||||||
} else if (!forTessellation && stage == kMVKGraphicsStageRasterization) {
|
} else if (!forTessellation && stage == kMVKGraphicsStageRasterization) {
|
||||||
encodeBindings(kMVKShaderStageVertex, "vertex", fullImageViewSwizzle,
|
encodeBindings(kMVKShaderStageVertex, "vertex", fullImageViewSwizzle,
|
||||||
[pipeline](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
|
[pipeline, isDynamicVertexStride](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
|
||||||
// The app may have bound more vertex attribute buffers than used by the pipeline.
|
// The app may have bound more vertex attribute buffers than used by the pipeline.
|
||||||
// We must not bind those extra buffers to the shader because they might overwrite
|
// We must not bind those extra buffers to the shader because they might overwrite
|
||||||
// any implicit buffers used by the pipeline.
|
// any implicit buffers used by the pipeline.
|
||||||
if (pipeline->isValidVertexBufferIndex(kMVKShaderStageVertex, b.index)) {
|
if (pipeline->isValidVertexBufferIndex(kMVKShaderStageVertex, b.index)) {
|
||||||
if (b.isInline) {
|
cmdEncoder->encodeVertexAttributeBuffer(b, isDynamicVertexStride);
|
||||||
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
|
|
||||||
b.mtlBytes,
|
|
||||||
b.size,
|
|
||||||
b.index);
|
|
||||||
} else {
|
|
||||||
if (b.justOffset) {
|
|
||||||
[cmdEncoder->_mtlRenderEncoder setVertexBufferOffset: b.offset
|
|
||||||
atIndex: b.index];
|
|
||||||
} else {
|
|
||||||
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
|
|
||||||
offset: b.offset
|
|
||||||
atIndex: b.index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add any translated vertex bindings for this binding
|
// Add any translated vertex bindings for this binding
|
||||||
|
if ( !b.isInline ) {
|
||||||
auto xltdVtxBindings = pipeline->getTranslatedVertexBindings();
|
auto xltdVtxBindings = pipeline->getTranslatedVertexBindings();
|
||||||
for (auto& xltdBind : xltdVtxBindings) {
|
for (auto& xltdBind : xltdVtxBindings) {
|
||||||
if (b.index == pipeline->getMetalBufferIndexForVertexAttributeBinding(xltdBind.binding)) {
|
if (b.index == pipeline->getMetalBufferIndexForVertexAttributeBinding(xltdBind.binding)) {
|
||||||
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
|
MVKMTLBufferBinding bx = {
|
||||||
offset: b.offset + xltdBind.translationOffset
|
.mtlBuffer = b.mtlBuffer,
|
||||||
atIndex: pipeline->getMetalBufferIndexForVertexAttributeBinding(xltdBind.translationBinding)];
|
.offset = b.offset + xltdBind.translationOffset,
|
||||||
|
.stride = b.stride,
|
||||||
|
.index = static_cast<uint16_t>(pipeline->getMetalBufferIndexForVertexAttributeBinding(xltdBind.translationBinding)) };
|
||||||
|
cmdEncoder->encodeVertexAttributeBuffer(bx, isDynamicVertexStride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -898,19 +948,8 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
|
|||||||
|
|
||||||
if (forTessellation && stage == kMVKGraphicsStageRasterization) {
|
if (forTessellation && stage == kMVKGraphicsStageRasterization) {
|
||||||
encodeBindings(kMVKShaderStageTessEval, "tessellation evaluation", fullImageViewSwizzle,
|
encodeBindings(kMVKShaderStageTessEval, "tessellation evaluation", fullImageViewSwizzle,
|
||||||
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
|
[isDynamicVertexStride](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
|
||||||
if (b.isInline)
|
cmdEncoder->encodeVertexAttributeBuffer(b, isDynamicVertexStride);
|
||||||
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
|
|
||||||
b.mtlBytes,
|
|
||||||
b.size,
|
|
||||||
b.index);
|
|
||||||
else if (b.justOffset)
|
|
||||||
[cmdEncoder->_mtlRenderEncoder setVertexBufferOffset: b.offset
|
|
||||||
atIndex: b.index];
|
|
||||||
else
|
|
||||||
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
|
|
||||||
offset: b.offset
|
|
||||||
atIndex: b.index];
|
|
||||||
},
|
},
|
||||||
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKArrayRef<const uint32_t> s)->void {
|
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKArrayRef<const uint32_t> s)->void {
|
||||||
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
|
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "MVKCommandEncodingPool.h"
|
#include "MVKCommandEncodingPool.h"
|
||||||
#include "MVKCommand.h"
|
#include "MVKCommand.h"
|
||||||
#include "MVKCmdPipeline.h"
|
#include "MVKCmdPipeline.h"
|
||||||
#include "MVKCmdRenderPass.h"
|
#include "MVKCmdRendering.h"
|
||||||
#include "MVKCmdDispatch.h"
|
#include "MVKCmdDispatch.h"
|
||||||
#include "MVKCmdDraw.h"
|
#include "MVKCmdDraw.h"
|
||||||
#include "MVKCmdTransfer.h"
|
#include "MVKCmdTransfer.h"
|
||||||
|
@ -210,27 +210,24 @@ namespace std {
|
|||||||
* change as early as possible.
|
* change as early as possible.
|
||||||
*/
|
*/
|
||||||
typedef struct MVKMTLStencilDescriptorData {
|
typedef struct MVKMTLStencilDescriptorData {
|
||||||
bool enabled; /**< Indicates whether stencil testing for this face is enabled. */
|
uint32_t readMask; /**< The bit-mask to apply when comparing the stencil buffer value to the reference value. */
|
||||||
|
uint32_t writeMask; /**< The bit-mask to apply when writing values to the stencil buffer. */
|
||||||
uint8_t stencilCompareFunction; /**< The stencil compare function (interpreted as MTLCompareFunction). */
|
uint8_t stencilCompareFunction; /**< The stencil compare function (interpreted as MTLCompareFunction). */
|
||||||
uint8_t stencilFailureOperation; /**< The operation to take when the stencil test fails (interpreted as MTLStencilOperation). */
|
uint8_t stencilFailureOperation; /**< The operation to take when the stencil test fails (interpreted as MTLStencilOperation). */
|
||||||
uint8_t depthFailureOperation; /**< The operation to take when the stencil test passes, but the depth test fails (interpreted as MTLStencilOperation). */
|
uint8_t depthFailureOperation; /**< The operation to take when the stencil test passes, but the depth test fails (interpreted as MTLStencilOperation). */
|
||||||
uint8_t depthStencilPassOperation; /**< The operation to take when both the stencil and depth tests pass (interpreted as MTLStencilOperation). */
|
uint8_t depthStencilPassOperation; /**< The operation to take when both the stencil and depth tests pass (interpreted as MTLStencilOperation). */
|
||||||
uint32_t readMask; /**< The bit-mask to apply when comparing the stencil buffer value to the reference value. */
|
|
||||||
uint32_t writeMask; /**< The bit-mask to apply when writing values to the stencil buffer. */
|
bool operator==(const MVKMTLStencilDescriptorData& rhs) const { return mvkAreEqual(this, &rhs); }
|
||||||
|
bool operator!=(const MVKMTLStencilDescriptorData& rhs) const { return !(*this == rhs); }
|
||||||
|
|
||||||
MVKMTLStencilDescriptorData() {
|
MVKMTLStencilDescriptorData() {
|
||||||
|
mvkClear(this); // Clear all memory to ensure memory comparisons will work.
|
||||||
// Start with all zeros to ensure memory comparisons will work,
|
mvkEnableAllFlags(readMask);
|
||||||
// even if the structure contains alignment gaps.
|
mvkEnableAllFlags(writeMask);
|
||||||
mvkClear(this);
|
|
||||||
|
|
||||||
enabled = false;
|
|
||||||
stencilCompareFunction = MTLCompareFunctionAlways;
|
stencilCompareFunction = MTLCompareFunctionAlways;
|
||||||
stencilFailureOperation = MTLStencilOperationKeep;
|
stencilFailureOperation = MTLStencilOperationKeep;
|
||||||
depthFailureOperation = MTLStencilOperationKeep;
|
depthFailureOperation = MTLStencilOperationKeep;
|
||||||
depthStencilPassOperation = MTLStencilOperationKeep;
|
depthStencilPassOperation = MTLStencilOperationKeep;
|
||||||
readMask = static_cast<uint32_t>(~0);
|
|
||||||
writeMask = static_cast<uint32_t>(~0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} MVKMTLStencilDescriptorData;
|
} MVKMTLStencilDescriptorData;
|
||||||
@ -247,34 +244,32 @@ const MVKMTLStencilDescriptorData kMVKMTLStencilDescriptorDataDefault;
|
|||||||
* change as early as possible.
|
* change as early as possible.
|
||||||
*/
|
*/
|
||||||
typedef struct MVKMTLDepthStencilDescriptorData {
|
typedef struct MVKMTLDepthStencilDescriptorData {
|
||||||
uint8_t depthCompareFunction; /**< The depth compare function (interpreted as MTLCompareFunction). */
|
|
||||||
bool depthWriteEnabled; /**< Indicates whether depth writing is enabled. */
|
|
||||||
MVKMTLStencilDescriptorData frontFaceStencilData;
|
MVKMTLStencilDescriptorData frontFaceStencilData;
|
||||||
MVKMTLStencilDescriptorData backFaceStencilData;
|
MVKMTLStencilDescriptorData backFaceStencilData;
|
||||||
|
uint8_t depthCompareFunction; /**< The depth compare function (interpreted as MTLCompareFunction). */
|
||||||
|
bool depthWriteEnabled; /**< Indicates whether depth writing is enabled. */
|
||||||
|
bool stencilTestEnabled; /**< Indicates whether stencil testing is enabled. */
|
||||||
|
|
||||||
bool operator==(const MVKMTLDepthStencilDescriptorData& rhs) const { return mvkAreEqual(this, &rhs); }
|
bool operator==(const MVKMTLDepthStencilDescriptorData& rhs) const { return mvkAreEqual(this, &rhs); }
|
||||||
|
bool operator!=(const MVKMTLDepthStencilDescriptorData& rhs) const { return !(*this == rhs); }
|
||||||
|
|
||||||
std::size_t hash() const {
|
std::size_t hash() const {
|
||||||
return mvkHash((uint64_t*)this, sizeof(*this) / sizeof(uint64_t));
|
return mvkHash((uint64_t*)this, sizeof(*this) / sizeof(uint64_t));
|
||||||
}
|
}
|
||||||
|
void disableDepth() {
|
||||||
/** Disable depth and/or stencil testing. */
|
|
||||||
void disable(bool disableDepth, bool disableStencil) {
|
|
||||||
if (disableDepth) {
|
|
||||||
depthCompareFunction = MTLCompareFunctionAlways;
|
depthCompareFunction = MTLCompareFunctionAlways;
|
||||||
depthWriteEnabled = false;
|
depthWriteEnabled = false;
|
||||||
}
|
}
|
||||||
if (disableStencil) {
|
void disableStencil() {
|
||||||
|
stencilTestEnabled = false;
|
||||||
frontFaceStencilData = kMVKMTLStencilDescriptorDataDefault;
|
frontFaceStencilData = kMVKMTLStencilDescriptorDataDefault;
|
||||||
backFaceStencilData = kMVKMTLStencilDescriptorDataDefault;
|
backFaceStencilData = kMVKMTLStencilDescriptorDataDefault;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MVKMTLDepthStencilDescriptorData() {
|
MVKMTLDepthStencilDescriptorData() {
|
||||||
// Start with all zeros to ensure memory comparisons will work,
|
mvkClear(this); // Clear all memory to ensure memory comparisons will work.
|
||||||
// even if the structure contains alignment gaps.
|
disableDepth();
|
||||||
mvkClear(this);
|
disableStencil();
|
||||||
disable(true, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} __attribute__((aligned(sizeof(uint64_t)))) MVKMTLDepthStencilDescriptorData;
|
} __attribute__((aligned(sizeof(uint64_t)))) MVKMTLDepthStencilDescriptorData;
|
||||||
|
@ -433,9 +433,10 @@ id<MTLDepthStencilState> MVKCommandResourceFactory::newMTLDepthStencilState(bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
id<MTLDepthStencilState> MVKCommandResourceFactory::newMTLDepthStencilState(MVKMTLDepthStencilDescriptorData& dsData) {
|
id<MTLDepthStencilState> MVKCommandResourceFactory::newMTLDepthStencilState(MVKMTLDepthStencilDescriptorData& dsData) {
|
||||||
MTLStencilDescriptor* fsDesc = newMTLStencilDescriptor(dsData.frontFaceStencilData); // temp retain
|
bool testStencil = dsData.stencilTestEnabled;
|
||||||
MTLStencilDescriptor* bsDesc = newMTLStencilDescriptor(dsData.backFaceStencilData); // temp retain
|
auto* fsDesc = testStencil ? newMTLStencilDescriptor(dsData.frontFaceStencilData) : nil; // temp retain
|
||||||
MTLDepthStencilDescriptor* dsDesc = [MTLDepthStencilDescriptor new]; // temp retain
|
auto* bsDesc = testStencil ? newMTLStencilDescriptor(dsData.backFaceStencilData) : nil; // temp retain
|
||||||
|
auto* dsDesc = [MTLDepthStencilDescriptor new]; // temp retain
|
||||||
dsDesc.depthCompareFunction = (MTLCompareFunction)dsData.depthCompareFunction;
|
dsDesc.depthCompareFunction = (MTLCompareFunction)dsData.depthCompareFunction;
|
||||||
dsDesc.depthWriteEnabled = dsData.depthWriteEnabled;
|
dsDesc.depthWriteEnabled = dsData.depthWriteEnabled;
|
||||||
dsDesc.frontFaceStencil = fsDesc;
|
dsDesc.frontFaceStencil = fsDesc;
|
||||||
@ -451,8 +452,6 @@ id<MTLDepthStencilState> MVKCommandResourceFactory::newMTLDepthStencilState(MVKM
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTLStencilDescriptor* MVKCommandResourceFactory::newMTLStencilDescriptor(MVKMTLStencilDescriptorData& sData) {
|
MTLStencilDescriptor* MVKCommandResourceFactory::newMTLStencilDescriptor(MVKMTLStencilDescriptorData& sData) {
|
||||||
if ( !sData.enabled ) { return nil; }
|
|
||||||
|
|
||||||
MTLStencilDescriptor* sDesc = [MTLStencilDescriptor new]; // retained
|
MTLStencilDescriptor* sDesc = [MTLStencilDescriptor new]; // retained
|
||||||
sDesc.stencilCompareFunction = (MTLCompareFunction)sData.stencilCompareFunction;
|
sDesc.stencilCompareFunction = (MTLCompareFunction)sData.stencilCompareFunction;
|
||||||
sDesc.stencilFailureOperation = (MTLStencilOperation)sData.stencilFailureOperation;
|
sDesc.stencilFailureOperation = (MTLStencilOperation)sData.stencilFailureOperation;
|
||||||
|
@ -86,13 +86,23 @@ MVK_CMD_TYPE_POOLS_FROM_2_THRESHOLDS(BindDescriptorSetsStatic, 1, 4)
|
|||||||
MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(BindDescriptorSetsDynamic, 4)
|
MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(BindDescriptorSetsDynamic, 4)
|
||||||
MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(SetViewport, 1)
|
MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(SetViewport, 1)
|
||||||
MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(SetScissor, 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(SetBlendConstants)
|
||||||
MVK_CMD_TYPE_POOL(SetDepthBounds)
|
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)
|
||||||
|
MVK_CMD_TYPE_POOL(SetStencilTestEnable)
|
||||||
|
MVK_CMD_TYPE_POOL(SetStencilOp)
|
||||||
MVK_CMD_TYPE_POOL(SetStencilCompareMask)
|
MVK_CMD_TYPE_POOL(SetStencilCompareMask)
|
||||||
MVK_CMD_TYPE_POOL(SetStencilWriteMask)
|
MVK_CMD_TYPE_POOL(SetStencilWriteMask)
|
||||||
MVK_CMD_TYPE_POOL(SetStencilReference)
|
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_POOLS_FROM_2_THRESHOLDS(BindVertexBuffers, 1, 2)
|
||||||
MVK_CMD_TYPE_POOL(BindIndexBuffer)
|
MVK_CMD_TYPE_POOL(BindIndexBuffer)
|
||||||
MVK_CMD_TYPE_POOL(Draw)
|
MVK_CMD_TYPE_POOL(Draw)
|
||||||
|
@ -67,6 +67,7 @@ typedef struct MVKMTLBufferBinding {
|
|||||||
union { id<MTLBuffer> mtlBuffer = nil; id<MTLBuffer> mtlResource; const void* mtlBytes; }; // aliases
|
union { id<MTLBuffer> mtlBuffer = nil; id<MTLBuffer> mtlResource; const void* mtlBytes; }; // aliases
|
||||||
VkDeviceSize offset = 0;
|
VkDeviceSize offset = 0;
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
|
uint32_t stride = 0;
|
||||||
uint16_t index = 0;
|
uint16_t index = 0;
|
||||||
bool justOffset = false;
|
bool justOffset = false;
|
||||||
bool isDirty = true;
|
bool isDirty = true;
|
||||||
@ -78,14 +79,16 @@ typedef struct MVKMTLBufferBinding {
|
|||||||
void update(const MVKMTLBufferBinding &other) {
|
void update(const MVKMTLBufferBinding &other) {
|
||||||
if (mtlBuffer != other.mtlBuffer || size != other.size || other.isInline) {
|
if (mtlBuffer != other.mtlBuffer || size != other.size || other.isInline) {
|
||||||
mtlBuffer = other.mtlBuffer;
|
mtlBuffer = other.mtlBuffer;
|
||||||
size = other.size;
|
|
||||||
isInline = other.isInline;
|
|
||||||
offset = other.offset;
|
offset = other.offset;
|
||||||
|
size = other.size;
|
||||||
|
stride = other.stride;
|
||||||
|
isInline = other.isInline;
|
||||||
justOffset = false;
|
justOffset = false;
|
||||||
isOverridden = false;
|
isOverridden = false;
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
} else if (offset != other.offset) {
|
} else if (offset != other.offset || stride != other.stride) {
|
||||||
offset = other.offset;
|
offset = other.offset;
|
||||||
|
stride = other.stride;
|
||||||
justOffset = !isOverridden && (!isDirty || justOffset);
|
justOffset = !isOverridden && (!isDirty || justOffset);
|
||||||
isOverridden = false;
|
isOverridden = false;
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
|
@ -387,6 +387,18 @@ void MVKPhysicalDevice::getFeatures(VkPhysicalDeviceFeatures2* features) {
|
|||||||
formatFeatures->formatA4B4G4R4 = canSupport4444;
|
formatFeatures->formatA4B4G4R4 = canSupport4444;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {
|
||||||
|
auto* extDynState = (VkPhysicalDeviceExtendedDynamicStateFeaturesEXT*)next;
|
||||||
|
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: {
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {
|
||||||
auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
|
auto* interlockFeatures = (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT*)next;
|
||||||
interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups;
|
interlockFeatures->fragmentShaderSampleInterlock = _metalFeatures.rasterOrderGroups;
|
||||||
@ -1696,10 +1708,11 @@ void MVKPhysicalDevice::initMetalFeatures() {
|
|||||||
_metalFeatures.minSwapchainImageCount = kMVKMinSwapchainImageCount;
|
_metalFeatures.minSwapchainImageCount = kMVKMinSwapchainImageCount;
|
||||||
_metalFeatures.maxSwapchainImageCount = kMVKMaxSwapchainImageCount;
|
_metalFeatures.maxSwapchainImageCount = kMVKMaxSwapchainImageCount;
|
||||||
|
|
||||||
_metalFeatures.vertexStrideAlignment = 4;
|
|
||||||
|
|
||||||
_metalFeatures.maxPerStageStorageTextureCount = 8;
|
_metalFeatures.maxPerStageStorageTextureCount = 8;
|
||||||
|
|
||||||
|
_metalFeatures.vertexStrideAlignment = supportsMTLGPUFamily(Apple5) ? 1 : 4;
|
||||||
|
_metalFeatures.dynamicVertexStride = mvkOSVersionIsAtLeast(14.0, 17.0, 1.0) && (supportsMTLGPUFamily(Apple4) || supportsMTLGPUFamily(Mac2));
|
||||||
|
|
||||||
// GPU-specific features
|
// GPU-specific features
|
||||||
switch (_properties.vendorID) {
|
switch (_properties.vendorID) {
|
||||||
case kAMDVendorId:
|
case kAMDVendorId:
|
||||||
@ -2411,7 +2424,7 @@ void MVKPhysicalDevice::initLimits() {
|
|||||||
_properties.limits.maxVertexInputAttributes = 31;
|
_properties.limits.maxVertexInputAttributes = 31;
|
||||||
_properties.limits.maxVertexInputBindings = 31;
|
_properties.limits.maxVertexInputBindings = 31;
|
||||||
|
|
||||||
_properties.limits.maxVertexInputBindingStride = (2 * KIBI);
|
_properties.limits.maxVertexInputBindingStride = supportsMTLGPUFamily(Apple2) ? kMVKUndefinedLargeUInt32 : (4 * KIBI);
|
||||||
_properties.limits.maxVertexInputAttributeOffset = _properties.limits.maxVertexInputBindingStride - 1;
|
_properties.limits.maxVertexInputAttributeOffset = _properties.limits.maxVertexInputBindingStride - 1;
|
||||||
|
|
||||||
_properties.limits.maxPerStageDescriptorSamplers = _metalFeatures.maxPerStageSamplerCount;
|
_properties.limits.maxPerStageDescriptorSamplers = _metalFeatures.maxPerStageSamplerCount;
|
||||||
|
@ -64,6 +64,8 @@ MVK_DEVICE_FEATURE(VulkanMemoryModel, VULKAN_MEMORY_MODEL,
|
|||||||
MVK_DEVICE_FEATURE_EXTN(FragmentShaderBarycentric, FRAGMENT_SHADER_BARYCENTRIC, KHR, 1)
|
MVK_DEVICE_FEATURE_EXTN(FragmentShaderBarycentric, FRAGMENT_SHADER_BARYCENTRIC, KHR, 1)
|
||||||
MVK_DEVICE_FEATURE_EXTN(PortabilitySubset, PORTABILITY_SUBSET, KHR, 15)
|
MVK_DEVICE_FEATURE_EXTN(PortabilitySubset, PORTABILITY_SUBSET, KHR, 15)
|
||||||
MVK_DEVICE_FEATURE_EXTN(4444Formats, 4444_FORMATS, EXT, 2)
|
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(FragmentShaderInterlock, FRAGMENT_SHADER_INTERLOCK, EXT, 3)
|
||||||
MVK_DEVICE_FEATURE_EXTN(PipelineCreationCacheControl, PIPELINE_CREATION_CACHE_CONTROL, EXT, 1)
|
MVK_DEVICE_FEATURE_EXTN(PipelineCreationCacheControl, PIPELINE_CREATION_CACHE_CONTROL, EXT, 1)
|
||||||
MVK_DEVICE_FEATURE_EXTN(Robustness2, ROBUSTNESS_2, EXT, 3)
|
MVK_DEVICE_FEATURE_EXTN(Robustness2, ROBUSTNESS_2, EXT, 3)
|
||||||
|
@ -635,16 +635,16 @@ void MVKInstance::initProcAddrs() {
|
|||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdResetEvent2, KHR, KHR_SYNCHRONIZATION_2);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdResetEvent2, KHR, KHR_SYNCHRONIZATION_2);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdResolveImage2, KHR, KHR_COPY_COMMANDS_2);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdResolveImage2, KHR, KHR_COPY_COMMANDS_2);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetCullMode, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetCullMode, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthBiasEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthBiasEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE_2);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthBoundsTestEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthBoundsTestEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthCompareOp, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthCompareOp, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthTestEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthTestEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthWriteEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetDepthWriteEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetEvent2, KHR, KHR_SYNCHRONIZATION_2);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetEvent2, KHR, KHR_SYNCHRONIZATION_2);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetFrontFace, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetFrontFace, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetPrimitiveRestartEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetPrimitiveRestartEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE_2);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetPrimitiveTopology, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetPrimitiveTopology, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetRasterizerDiscardEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetRasterizerDiscardEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE_2);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetScissorWithCount, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetScissorWithCount, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetStencilOp, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetStencilOp, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetStencilTestEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkCmdSetStencilTestEnable, EXT, EXT_EXTENDED_DYNAMIC_STATE);
|
||||||
@ -698,6 +698,9 @@ void MVKInstance::initProcAddrs() {
|
|||||||
ADD_DVC_EXT_ENTRY_POINT(vkReleaseSwapchainImagesEXT, EXT_SWAPCHAIN_MAINTENANCE_1);
|
ADD_DVC_EXT_ENTRY_POINT(vkReleaseSwapchainImagesEXT, EXT_SWAPCHAIN_MAINTENANCE_1);
|
||||||
ADD_DVC_EXT_ENTRY_POINT(vkGetRefreshCycleDurationGOOGLE, GOOGLE_DISPLAY_TIMING);
|
ADD_DVC_EXT_ENTRY_POINT(vkGetRefreshCycleDurationGOOGLE, GOOGLE_DISPLAY_TIMING);
|
||||||
ADD_DVC_EXT_ENTRY_POINT(vkGetPastPresentationTimingGOOGLE, 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() {
|
void MVKInstance::logVersions() {
|
||||||
|
@ -218,6 +218,49 @@ struct MVKStagedDescriptorBindingUse {
|
|||||||
MVKBitArray stages[4] = {};
|
MVKBitArray stages[4] = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Enumeration identifying different state content types. */
|
||||||
|
enum MVKRenderStateType {
|
||||||
|
Unknown = 0,
|
||||||
|
BlendConstants,
|
||||||
|
CullMode,
|
||||||
|
DepthBias,
|
||||||
|
DepthBiasEnable,
|
||||||
|
DepthBounds,
|
||||||
|
DepthBoundsTestEnable,
|
||||||
|
DepthClipEnable,
|
||||||
|
DepthCompareOp,
|
||||||
|
DepthTestEnable,
|
||||||
|
DepthWriteEnable,
|
||||||
|
FrontFace,
|
||||||
|
LogicOp,
|
||||||
|
LogicOpEnable,
|
||||||
|
PatchControlPoints,
|
||||||
|
PolygonMode,
|
||||||
|
PrimitiveRestartEnable,
|
||||||
|
PrimitiveTopology,
|
||||||
|
RasterizerDiscardEnable,
|
||||||
|
SampleLocations,
|
||||||
|
Scissors,
|
||||||
|
StencilCompareMask,
|
||||||
|
StencilOp,
|
||||||
|
StencilReference,
|
||||||
|
StencilTestEnable,
|
||||||
|
StencilWriteMask,
|
||||||
|
VertexStride,
|
||||||
|
Viewports,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Boolean tracking of rendering state. */
|
||||||
|
struct MVKRenderStateFlags {
|
||||||
|
void enable(MVKRenderStateType rs) { if (rs) { mvkEnableFlags(_stateFlags, getFlagMask(rs)); } }
|
||||||
|
void disable(MVKRenderStateType rs) { if (rs) { mvkDisableFlags(_stateFlags, getFlagMask(rs)); } }
|
||||||
|
bool isEnabled(MVKRenderStateType rs) { return mvkIsAnyFlagEnabled(_stateFlags, getFlagMask(rs)); }
|
||||||
|
protected:
|
||||||
|
uint32_t getFlagMask(MVKRenderStateType rs) { return rs ? (1u << (rs - 1u)) : 0; } // Ignore Unknown type
|
||||||
|
|
||||||
|
uint32_t _stateFlags = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/** Represents an Vulkan graphics pipeline. */
|
/** Represents an Vulkan graphics pipeline. */
|
||||||
class MVKGraphicsPipeline : public MVKPipeline {
|
class MVKGraphicsPipeline : public MVKPipeline {
|
||||||
|
|
||||||
@ -229,15 +272,12 @@ public:
|
|||||||
/** Binds this pipeline to the specified command encoder. */
|
/** Binds this pipeline to the specified command encoder. */
|
||||||
void encode(MVKCommandEncoder* cmdEncoder, uint32_t stage = 0) override;
|
void encode(MVKCommandEncoder* cmdEncoder, uint32_t stage = 0) override;
|
||||||
|
|
||||||
/** Returns whether this pipeline permits dynamic setting of the specifie state. */
|
/** Returns whether this pipeline permits dynamic setting of the state. */
|
||||||
bool supportsDynamicState(VkDynamicState state);
|
bool isDynamicState(MVKRenderStateType state) { return _dynamicState.isEnabled(state); }
|
||||||
|
|
||||||
/** Returns whether this pipeline has tessellation shaders. */
|
/** Returns whether this pipeline has tessellation shaders. */
|
||||||
bool isTessellationPipeline() { return _tessInfo.patchControlPoints > 0; }
|
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. */
|
/** Returns the number of output tessellation patch control points. */
|
||||||
uint32_t getOutputControlPointCount() { return _outputControlPointCount; }
|
uint32_t getOutputControlPointCount() { return _outputControlPointCount; }
|
||||||
|
|
||||||
@ -313,6 +353,8 @@ public:
|
|||||||
~MVKGraphicsPipeline() override;
|
~MVKGraphicsPipeline() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend class MVKGraphicsPipelineCommandEncoderState;
|
||||||
|
|
||||||
typedef MVKSmallVector<SPIRVShaderInterfaceVariable, 32> SPIRVShaderOutputs;
|
typedef MVKSmallVector<SPIRVShaderInterfaceVariable, 32> SPIRVShaderOutputs;
|
||||||
typedef MVKSmallVector<SPIRVShaderInterfaceVariable, 32> SPIRVShaderInputs;
|
typedef MVKSmallVector<SPIRVShaderInterfaceVariable, 32> SPIRVShaderInputs;
|
||||||
|
|
||||||
@ -320,6 +362,7 @@ protected:
|
|||||||
id<MTLComputePipelineState> getOrCompilePipeline(MTLComputePipelineDescriptor* plDesc, id<MTLComputePipelineState>& plState, const char* compilerType);
|
id<MTLComputePipelineState> getOrCompilePipeline(MTLComputePipelineDescriptor* plDesc, id<MTLComputePipelineState>& plState, const char* compilerType);
|
||||||
bool compileTessVertexStageState(MTLComputePipelineDescriptor* vtxPLDesc, MVKMTLFunction* pVtxFunctions, VkPipelineCreationFeedback* pVertexFB);
|
bool compileTessVertexStageState(MTLComputePipelineDescriptor* vtxPLDesc, MVKMTLFunction* pVtxFunctions, VkPipelineCreationFeedback* pVertexFB);
|
||||||
bool compileTessControlStageState(MTLComputePipelineDescriptor* tcPLDesc, VkPipelineCreationFeedback* pTessCtlFB);
|
bool compileTessControlStageState(MTLComputePipelineDescriptor* tcPLDesc, VkPipelineCreationFeedback* pTessCtlFB);
|
||||||
|
void initDynamicState(const VkGraphicsPipelineCreateInfo* pCreateInfo);
|
||||||
void initCustomSamplePositions(const VkGraphicsPipelineCreateInfo* pCreateInfo);
|
void initCustomSamplePositions(const VkGraphicsPipelineCreateInfo* pCreateInfo);
|
||||||
void initMTLRenderPipelineState(const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData, VkPipelineCreationFeedback* pPipelineFB, const VkPipelineShaderStageCreateInfo* pVertexSS, VkPipelineCreationFeedback* pVertexFB, const VkPipelineShaderStageCreateInfo* pTessCtlSS, VkPipelineCreationFeedback* pTessCtlFB, const VkPipelineShaderStageCreateInfo* pTessEvalSS, VkPipelineCreationFeedback* pTessEvalFB, const VkPipelineShaderStageCreateInfo* pFragmentSS, VkPipelineCreationFeedback* pFragmentFB);
|
void initMTLRenderPipelineState(const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData, VkPipelineCreationFeedback* pPipelineFB, const VkPipelineShaderStageCreateInfo* pVertexSS, VkPipelineCreationFeedback* pVertexFB, const VkPipelineShaderStageCreateInfo* pTessCtlSS, VkPipelineCreationFeedback* pTessCtlFB, const VkPipelineShaderStageCreateInfo* pTessEvalSS, VkPipelineCreationFeedback* pTessEvalFB, const VkPipelineShaderStageCreateInfo* pFragmentSS, VkPipelineCreationFeedback* pFragmentFB);
|
||||||
void initShaderConversionConfig(SPIRVToMSLConversionConfiguration& shaderConfig, const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData);
|
void initShaderConversionConfig(SPIRVToMSLConversionConfiguration& shaderConfig, const VkGraphicsPipelineCreateInfo* pCreateInfo, const SPIRVTessReflectionData& reflectData);
|
||||||
@ -356,10 +399,10 @@ protected:
|
|||||||
VkPipelineTessellationStateCreateInfo _tessInfo;
|
VkPipelineTessellationStateCreateInfo _tessInfo;
|
||||||
VkPipelineRasterizationStateCreateInfo _rasterInfo;
|
VkPipelineRasterizationStateCreateInfo _rasterInfo;
|
||||||
VkPipelineDepthStencilStateCreateInfo _depthStencilInfo;
|
VkPipelineDepthStencilStateCreateInfo _depthStencilInfo;
|
||||||
|
MVKRenderStateFlags _dynamicState;
|
||||||
|
|
||||||
MVKSmallVector<VkViewport, kMVKMaxViewportScissorCount> _viewports;
|
MVKSmallVector<VkViewport, kMVKMaxViewportScissorCount> _viewports;
|
||||||
MVKSmallVector<VkRect2D, kMVKMaxViewportScissorCount> _scissors;
|
MVKSmallVector<VkRect2D, kMVKMaxViewportScissorCount> _scissors;
|
||||||
MVKSmallVector<VkDynamicState> _dynamicState;
|
|
||||||
MVKSmallVector<MTLSamplePosition> _customSamplePositions;
|
MVKSmallVector<MTLSamplePosition> _customSamplePositions;
|
||||||
MVKSmallVector<MVKTranslatedVertexBinding> _translatedVertexBindings;
|
MVKSmallVector<MVKTranslatedVertexBinding> _translatedVertexBindings;
|
||||||
MVKSmallVector<MVKZeroDivisorVertexBinding> _zeroDivisorVertexBindings;
|
MVKSmallVector<MVKZeroDivisorVertexBinding> _zeroDivisorVertexBindings;
|
||||||
@ -374,11 +417,7 @@ protected:
|
|||||||
id<MTLComputePipelineState> _mtlTessControlStageState = nil;
|
id<MTLComputePipelineState> _mtlTessControlStageState = nil;
|
||||||
id<MTLRenderPipelineState> _mtlPipelineState = nil;
|
id<MTLRenderPipelineState> _mtlPipelineState = nil;
|
||||||
|
|
||||||
float _blendConstants[4] = { 0.0, 0.0, 0.0, 1.0 };
|
float _blendConstants[4] = {};
|
||||||
MTLCullMode _mtlCullMode;
|
|
||||||
MTLWinding _mtlFrontWinding;
|
|
||||||
MTLTriangleFillMode _mtlFillMode;
|
|
||||||
MTLDepthClipMode _mtlDepthClipMode;
|
|
||||||
MVKShaderImplicitRezBinding _reservedVertexAttributeBufferCount;
|
MVKShaderImplicitRezBinding _reservedVertexAttributeBufferCount;
|
||||||
MVKShaderImplicitRezBinding _viewRangeBufferIndex;
|
MVKShaderImplicitRezBinding _viewRangeBufferIndex;
|
||||||
MVKShaderImplicitRezBinding _outputBufferIndex;
|
MVKShaderImplicitRezBinding _outputBufferIndex;
|
||||||
@ -387,6 +426,7 @@ protected:
|
|||||||
uint32_t _tessCtlPatchOutputBufferIndex = 0;
|
uint32_t _tessCtlPatchOutputBufferIndex = 0;
|
||||||
uint32_t _tessCtlLevelBufferIndex = 0;
|
uint32_t _tessCtlLevelBufferIndex = 0;
|
||||||
|
|
||||||
|
bool _hasRasterInfo = false;
|
||||||
bool _needsVertexSwizzleBuffer = false;
|
bool _needsVertexSwizzleBuffer = false;
|
||||||
bool _needsVertexBufferSizeBuffer = false;
|
bool _needsVertexBufferSizeBuffer = false;
|
||||||
bool _needsVertexDynamicOffsetBuffer = false;
|
bool _needsVertexDynamicOffsetBuffer = false;
|
||||||
|
@ -292,24 +292,20 @@ void MVKGraphicsPipeline::encode(MVKCommandEncoder* cmdEncoder, uint32_t stage)
|
|||||||
|
|
||||||
// Depth stencil state - Cleared _depthStencilInfo values will disable depth testing
|
// Depth stencil state - Cleared _depthStencilInfo values will disable depth testing
|
||||||
cmdEncoder->_depthStencilState.setDepthStencilState(_depthStencilInfo);
|
cmdEncoder->_depthStencilState.setDepthStencilState(_depthStencilInfo);
|
||||||
cmdEncoder->_stencilReferenceValueState.setReferenceValues(_depthStencilInfo);
|
|
||||||
|
|
||||||
// Rasterization
|
// Rasterization
|
||||||
cmdEncoder->_blendColorState.setBlendColor(_blendConstants[0], _blendConstants[1],
|
cmdEncoder->_renderingState.setPrimitiveTopology(_vkPrimitiveTopology, false);
|
||||||
_blendConstants[2], _blendConstants[3], false);
|
cmdEncoder->_renderingState.setBlendConstants(_blendConstants, false);
|
||||||
cmdEncoder->_depthBiasState.setDepthBias(_rasterInfo);
|
cmdEncoder->_renderingState.setStencilReferenceValues(_depthStencilInfo);
|
||||||
cmdEncoder->_viewportState.setViewports(_viewports.contents(), 0, false);
|
cmdEncoder->_renderingState.setViewports(_viewports.contents(), 0, false);
|
||||||
cmdEncoder->_scissorState.setScissors(_scissors.contents(), 0, false);
|
cmdEncoder->_renderingState.setScissors(_scissors.contents(), 0, false);
|
||||||
cmdEncoder->_mtlPrimitiveType = mvkMTLPrimitiveTypeFromVkPrimitiveTopology(_vkPrimitiveTopology);
|
if (_hasRasterInfo) {
|
||||||
|
cmdEncoder->_renderingState.setCullMode(_rasterInfo.cullMode, false);
|
||||||
[mtlCmdEnc setCullMode: _mtlCullMode];
|
cmdEncoder->_renderingState.setFrontFace(_rasterInfo.frontFace, false);
|
||||||
[mtlCmdEnc setFrontFacingWinding: _mtlFrontWinding];
|
cmdEncoder->_renderingState.setPolygonMode(_rasterInfo.polygonMode, false);
|
||||||
[mtlCmdEnc setTriangleFillMode: _mtlFillMode];
|
cmdEncoder->_renderingState.setDepthBias(_rasterInfo);
|
||||||
|
cmdEncoder->_renderingState.setDepthClipEnable( !_rasterInfo.depthClampEnable, false );
|
||||||
if (_device->_enabledFeatures.depthClamp) {
|
|
||||||
[mtlCmdEnc setDepthClipMode: _mtlDepthClipMode];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,21 +316,6 @@ void MVKGraphicsPipeline::encode(MVKCommandEncoder* cmdEncoder, uint32_t stage)
|
|||||||
cmdEncoder->_graphicsResourcesState.bindViewRangeBuffer(_viewRangeBufferIndex, _needsVertexViewRangeBuffer, _needsFragmentViewRangeBuffer);
|
cmdEncoder->_graphicsResourcesState.bindViewRangeBuffer(_viewRangeBufferIndex, _needsVertexViewRangeBuffer, _needsFragmentViewRangeBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MVKGraphicsPipeline::supportsDynamicState(VkDynamicState state) {
|
|
||||||
for (auto& ds : _dynamicState) {
|
|
||||||
if (state == ds) {
|
|
||||||
// Some dynamic states have other restrictions
|
|
||||||
switch (state) {
|
|
||||||
case VK_DYNAMIC_STATE_DEPTH_BIAS:
|
|
||||||
return _rasterInfo.depthBiasEnable;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char vtxCompilerType[] = "Vertex stage pipeline for tessellation";
|
static const char vtxCompilerType[] = "Vertex stage pipeline for tessellation";
|
||||||
|
|
||||||
bool MVKGraphicsPipeline::compileTessVertexStageState(MTLComputePipelineDescriptor* vtxPLDesc,
|
bool MVKGraphicsPipeline::compileTessVertexStageState(MTLComputePipelineDescriptor* vtxPLDesc,
|
||||||
@ -414,6 +395,10 @@ MVKGraphicsPipeline::MVKGraphicsPipeline(MVKDevice* device,
|
|||||||
const VkGraphicsPipelineCreateInfo* pCreateInfo) :
|
const VkGraphicsPipelineCreateInfo* pCreateInfo) :
|
||||||
MVKPipeline(device, pipelineCache, (MVKPipelineLayout*)pCreateInfo->layout, pCreateInfo->flags, parent) {
|
MVKPipeline(device, pipelineCache, (MVKPipelineLayout*)pCreateInfo->layout, pCreateInfo->flags, parent) {
|
||||||
|
|
||||||
|
|
||||||
|
// Extract dynamic state first, as it can affect many configurations.
|
||||||
|
initDynamicState(pCreateInfo);
|
||||||
|
|
||||||
// Determine rasterization early, as various other structs are validated and interpreted in this context.
|
// Determine rasterization early, as various other structs are validated and interpreted in this context.
|
||||||
const VkPipelineRenderingCreateInfo* pRendInfo = getRenderingCreateInfo(pCreateInfo);
|
const VkPipelineRenderingCreateInfo* pRendInfo = getRenderingCreateInfo(pCreateInfo);
|
||||||
_isRasterizing = !isRasterizationDisabled(pCreateInfo);
|
_isRasterizing = !isRasterizationDisabled(pCreateInfo);
|
||||||
@ -509,17 +494,12 @@ MVKGraphicsPipeline::MVKGraphicsPipeline(MVKDevice* device,
|
|||||||
initMTLRenderPipelineState(pCreateInfo, reflectData, pPipelineFB, pVertexSS, pVertexFB, pTessCtlSS, pTessCtlFB, pTessEvalSS, pTessEvalFB, pFragmentSS, pFragmentFB);
|
initMTLRenderPipelineState(pCreateInfo, reflectData, pPipelineFB, pVertexSS, pVertexFB, pTessCtlSS, pTessCtlFB, pTessEvalSS, pTessEvalFB, pFragmentSS, pFragmentFB);
|
||||||
if ( !_hasValidMTLPipelineStates ) { return; }
|
if ( !_hasValidMTLPipelineStates ) { return; }
|
||||||
|
|
||||||
// Track dynamic state
|
|
||||||
const VkPipelineDynamicStateCreateInfo* pDS = pCreateInfo->pDynamicState;
|
|
||||||
if (pDS) {
|
|
||||||
for (uint32_t i = 0; i < pDS->dynamicStateCount; i++) {
|
|
||||||
_dynamicState.push_back(pDS->pDynamicStates[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blending - must ignore allowed bad pColorBlendState pointer if rasterization disabled or no color attachments
|
// Blending - must ignore allowed bad pColorBlendState pointer if rasterization disabled or no color attachments
|
||||||
if (_isRasterizingColor && pCreateInfo->pColorBlendState) {
|
if (_isRasterizingColor && pCreateInfo->pColorBlendState) {
|
||||||
memcpy(&_blendConstants, &pCreateInfo->pColorBlendState->blendConstants, sizeof(_blendConstants));
|
mvkCopy(_blendConstants, pCreateInfo->pColorBlendState->blendConstants, 4);
|
||||||
|
} else {
|
||||||
|
static float defaultBlendConstants[4] = { 0, 0.0, 0.0, 1.0 };
|
||||||
|
mvkCopy(_blendConstants, defaultBlendConstants, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Topology
|
// Topology
|
||||||
@ -527,24 +507,16 @@ MVKGraphicsPipeline::MVKGraphicsPipeline(MVKDevice* device,
|
|||||||
? pCreateInfo->pInputAssemblyState->topology
|
? pCreateInfo->pInputAssemblyState->topology
|
||||||
: VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
|
: 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
|
// Rasterization
|
||||||
_mtlCullMode = MTLCullModeNone;
|
_hasRasterInfo = mvkSetOrClear(&_rasterInfo, pCreateInfo->pRasterizationState);
|
||||||
_mtlFrontWinding = MTLWindingCounterClockwise;
|
|
||||||
_mtlFillMode = MTLTriangleFillModeFill;
|
|
||||||
_mtlDepthClipMode = MTLDepthClipModeClip;
|
|
||||||
bool hasRasterInfo = mvkSetOrClear(&_rasterInfo, pCreateInfo->pRasterizationState);
|
|
||||||
if (hasRasterInfo) {
|
|
||||||
_mtlCullMode = mvkMTLCullModeFromVkCullModeFlags(_rasterInfo.cullMode);
|
|
||||||
_mtlFrontWinding = mvkMTLWindingFromVkFrontFace(_rasterInfo.frontFace);
|
|
||||||
_mtlFillMode = mvkMTLTriangleFillModeFromVkPolygonMode(_rasterInfo.polygonMode);
|
|
||||||
if (_rasterInfo.depthClampEnable) {
|
|
||||||
if (_device->_enabledFeatures.depthClamp) {
|
|
||||||
_mtlDepthClipMode = MTLDepthClipModeClamp;
|
|
||||||
} else {
|
|
||||||
setConfigurationResult(reportError(VK_ERROR_FEATURE_NOT_PRESENT, "This device does not support depth clamping."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must run after _isRasterizing and _dynamicState are populated
|
// Must run after _isRasterizing and _dynamicState are populated
|
||||||
initCustomSamplePositions(pCreateInfo);
|
initCustomSamplePositions(pCreateInfo);
|
||||||
@ -557,26 +529,81 @@ MVKGraphicsPipeline::MVKGraphicsPipeline(MVKDevice* device,
|
|||||||
// Viewports and scissors - must ignore allowed bad pViewportState pointer if rasterization is disabled
|
// Viewports and scissors - must ignore allowed bad pViewportState pointer if rasterization is disabled
|
||||||
auto pVPState = _isRasterizing ? pCreateInfo->pViewportState : nullptr;
|
auto pVPState = _isRasterizing ? pCreateInfo->pViewportState : nullptr;
|
||||||
if (pVPState) {
|
if (pVPState) {
|
||||||
uint32_t vpCnt = pVPState->viewportCount;
|
|
||||||
|
// If viewports are dynamic, ignore them here.
|
||||||
|
uint32_t vpCnt = (pVPState->pViewports && !isDynamicState(Viewports)) ? pVPState->viewportCount : 0;
|
||||||
_viewports.reserve(vpCnt);
|
_viewports.reserve(vpCnt);
|
||||||
for (uint32_t vpIdx = 0; vpIdx < vpCnt; vpIdx++) {
|
for (uint32_t vpIdx = 0; vpIdx < vpCnt; vpIdx++) {
|
||||||
// If viewport is dyanamic, we still add a dummy so that the count will be tracked.
|
_viewports.push_back(pVPState->pViewports[vpIdx]);
|
||||||
VkViewport vp;
|
|
||||||
if ( !supportsDynamicState(VK_DYNAMIC_STATE_VIEWPORT) ) { vp = pVPState->pViewports[vpIdx]; }
|
|
||||||
_viewports.push_back(vp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t sCnt = pVPState->scissorCount;
|
// If scissors are dynamic, ignore them here.
|
||||||
|
uint32_t sCnt = (pVPState->pScissors && !isDynamicState(Scissors)) ? pVPState->scissorCount : 0;
|
||||||
_scissors.reserve(sCnt);
|
_scissors.reserve(sCnt);
|
||||||
for (uint32_t sIdx = 0; sIdx < sCnt; sIdx++) {
|
for (uint32_t sIdx = 0; sIdx < sCnt; sIdx++) {
|
||||||
// If scissor is dyanamic, we still add a dummy so that the count will be tracked.
|
_scissors.push_back(pVPState->pScissors[sIdx]);
|
||||||
VkRect2D sc;
|
|
||||||
if ( !supportsDynamicState(VK_DYNAMIC_STATE_SCISSOR) ) { sc = pVPState->pScissors[sIdx]; }
|
|
||||||
_scissors.push_back(sc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MVKRenderStateType getRenderStateType(VkDynamicState vkDynamicState) {
|
||||||
|
switch (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;
|
||||||
|
case VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT: return DepthClipEnable;
|
||||||
|
case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP: return DepthCompareOp;
|
||||||
|
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_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;
|
||||||
|
case VK_DYNAMIC_STATE_STENCIL_OP: return StencilOp;
|
||||||
|
case VK_DYNAMIC_STATE_STENCIL_REFERENCE: return StencilReference;
|
||||||
|
case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE: return StencilTestEnable;
|
||||||
|
case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: return StencilWriteMask;
|
||||||
|
case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE: return VertexStride;
|
||||||
|
case VK_DYNAMIC_STATE_VIEWPORT: return Viewports;
|
||||||
|
case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT: return Viewports;
|
||||||
|
default: return Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is executed first during pipeline creation. Do not depend on any internal state here.
|
||||||
|
void MVKGraphicsPipeline::initDynamicState(const VkGraphicsPipelineCreateInfo* pCreateInfo) {
|
||||||
|
const auto* pDS = pCreateInfo->pDynamicState;
|
||||||
|
if ( !pDS ) { return; }
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < pDS->dynamicStateCount; i++) {
|
||||||
|
auto dynStateType = getRenderStateType(pDS->pDynamicStates[i]);
|
||||||
|
bool isDynamic = true;
|
||||||
|
|
||||||
|
// Some dynamic states have other restrictions
|
||||||
|
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;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDynamic) { _dynamicState.enable(dynStateType); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Either returns an existing pipeline state or compiles a new one.
|
// Either returns an existing pipeline state or compiles a new one.
|
||||||
id<MTLRenderPipelineState> MVKGraphicsPipeline::getOrCompilePipeline(MTLRenderPipelineDescriptor* plDesc,
|
id<MTLRenderPipelineState> MVKGraphicsPipeline::getOrCompilePipeline(MTLRenderPipelineDescriptor* plDesc,
|
||||||
id<MTLRenderPipelineState>& plState) {
|
id<MTLRenderPipelineState>& plState) {
|
||||||
@ -613,7 +640,7 @@ void MVKGraphicsPipeline::initCustomSamplePositions(const VkGraphicsPipelineCrea
|
|||||||
case VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT: {
|
case VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT: {
|
||||||
auto* pSampLocnsCreateInfo = (VkPipelineSampleLocationsStateCreateInfoEXT*)next;
|
auto* pSampLocnsCreateInfo = (VkPipelineSampleLocationsStateCreateInfoEXT*)next;
|
||||||
_isUsingCustomSamplePositions = pSampLocnsCreateInfo->sampleLocationsEnable;
|
_isUsingCustomSamplePositions = pSampLocnsCreateInfo->sampleLocationsEnable;
|
||||||
if (_isUsingCustomSamplePositions && !supportsDynamicState(VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT)) {
|
if (_isUsingCustomSamplePositions && !isDynamicState(SampleLocations)) {
|
||||||
for (uint32_t slIdx = 0; slIdx < pSampLocnsCreateInfo->sampleLocationsInfo.sampleLocationsCount; slIdx++) {
|
for (uint32_t slIdx = 0; slIdx < pSampLocnsCreateInfo->sampleLocationsInfo.sampleLocationsCount; slIdx++) {
|
||||||
auto& sl = pSampLocnsCreateInfo->sampleLocationsInfo.pSampleLocations[slIdx];
|
auto& sl = pSampLocnsCreateInfo->sampleLocationsInfo.pSampleLocations[slIdx];
|
||||||
_customSamplePositions.push_back(MTLSamplePositionMake(sl.x, sl.y));
|
_customSamplePositions.push_back(MTLSamplePositionMake(sl.x, sl.y));
|
||||||
@ -1311,6 +1338,10 @@ bool MVKGraphicsPipeline::addFragmentShaderToPipeline(MTLRenderPipelineDescripto
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !MVK_XCODE_15
|
||||||
|
static const NSUInteger MTLBufferLayoutStrideDynamic = NSUIntegerMax;
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
bool MVKGraphicsPipeline::addVertexInputToPipeline(T* inputDesc,
|
bool MVKGraphicsPipeline::addVertexInputToPipeline(T* inputDesc,
|
||||||
const VkPipelineVertexInputStateCreateInfo* pVI,
|
const VkPipelineVertexInputStateCreateInfo* pVI,
|
||||||
@ -1328,8 +1359,9 @@ bool MVKGraphicsPipeline::addVertexInputToPipeline(T* inputDesc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vertex buffer bindings
|
// Vertex buffer bindings
|
||||||
uint32_t vbCnt = pVI->vertexBindingDescriptionCount;
|
bool isVtxStrideStatic = !isDynamicState(VertexStride);
|
||||||
uint32_t maxBinding = 0;
|
uint32_t maxBinding = 0;
|
||||||
|
uint32_t vbCnt = pVI->vertexBindingDescriptionCount;
|
||||||
for (uint32_t i = 0; i < vbCnt; i++) {
|
for (uint32_t i = 0; i < vbCnt; i++) {
|
||||||
const VkVertexInputBindingDescription* pVKVB = &pVI->pVertexBindingDescriptions[i];
|
const VkVertexInputBindingDescription* pVKVB = &pVI->pVertexBindingDescriptions[i];
|
||||||
if (shaderConfig.isVertexBufferUsed(pVKVB->binding)) {
|
if (shaderConfig.isVertexBufferUsed(pVKVB->binding)) {
|
||||||
@ -1352,7 +1384,7 @@ bool MVKGraphicsPipeline::addVertexInputToPipeline(T* inputDesc,
|
|||||||
vbDesc.stepFunction = (decltype(vbDesc.stepFunction))MTLStepFunctionConstant;
|
vbDesc.stepFunction = (decltype(vbDesc.stepFunction))MTLStepFunctionConstant;
|
||||||
vbDesc.stepRate = 0;
|
vbDesc.stepRate = 0;
|
||||||
} else {
|
} else {
|
||||||
vbDesc.stride = pVKVB->stride;
|
vbDesc.stride = isVtxStrideStatic ? pVKVB->stride : MTLBufferLayoutStrideDynamic;
|
||||||
vbDesc.stepFunction = (decltype(vbDesc.stepFunction))mvkMTLStepFunctionFromVkVertexInputRate(pVKVB->inputRate, isTessellationPipeline());
|
vbDesc.stepFunction = (decltype(vbDesc.stepFunction))mvkMTLStepFunctionFromVkVertexInputRate(pVKVB->inputRate, isTessellationPipeline());
|
||||||
vbDesc.stepRate = 1;
|
vbDesc.stepRate = 1;
|
||||||
}
|
}
|
||||||
@ -1903,11 +1935,12 @@ bool MVKGraphicsPipeline::isRenderingPoints(const VkGraphicsPipelineCreateInfo*
|
|||||||
(pCreateInfo->pRasterizationState && (pCreateInfo->pRasterizationState->polygonMode == VK_POLYGON_MODE_POINT)));
|
(pCreateInfo->pRasterizationState && (pCreateInfo->pRasterizationState->polygonMode == VK_POLYGON_MODE_POINT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We disable rasterization if either rasterizerDiscard is enabled or the 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) {
|
bool MVKGraphicsPipeline::isRasterizationDisabled(const VkGraphicsPipelineCreateInfo* pCreateInfo) {
|
||||||
return (pCreateInfo->pRasterizationState &&
|
return (pCreateInfo->pRasterizationState &&
|
||||||
(pCreateInfo->pRasterizationState->rasterizerDiscardEnable ||
|
((pCreateInfo->pRasterizationState->rasterizerDiscardEnable && !isDynamicState(RasterizerDiscardEnable)) ||
|
||||||
((pCreateInfo->pRasterizationState->cullMode == VK_CULL_MODE_FRONT_AND_BACK) && pCreateInfo->pInputAssemblyState &&
|
((pCreateInfo->pRasterizationState->cullMode == VK_CULL_MODE_FRONT_AND_BACK) && !isDynamicState(CullMode) &&
|
||||||
|
pCreateInfo->pInputAssemblyState &&
|
||||||
(mvkMTLPrimitiveTopologyClassFromVkPrimitiveTopology(pCreateInfo->pInputAssemblyState->topology) == MTLPrimitiveTopologyClassTriangle))));
|
(mvkMTLPrimitiveTopologyClassFromVkPrimitiveTopology(pCreateInfo->pInputAssemblyState->topology) == MTLPrimitiveTopologyClassTriangle))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +103,8 @@ MVK_EXTENSION(EXT_debug_marker, EXT_DEBUG_MARKER,
|
|||||||
MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT, INSTANCE, 10.11, 8.0, 1.0)
|
MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT, INSTANCE, 10.11, 8.0, 1.0)
|
||||||
MVK_EXTENSION(EXT_debug_utils, EXT_DEBUG_UTILS, INSTANCE, 10.11, 8.0, 1.0)
|
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_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_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_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)
|
MVK_EXTENSION(EXT_hdr_metadata, EXT_HDR_METADATA, DEVICE, 10.15, MVK_NA, MVK_NA)
|
||||||
|
@ -60,6 +60,9 @@ typedef struct {
|
|||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark Vulkan support
|
#pragma mark Vulkan support
|
||||||
|
|
||||||
|
/** A generic 32-bit color permitting float, int32, or uint32 values. */
|
||||||
|
typedef VkClearColorValue MVKColor32;
|
||||||
|
|
||||||
/** Tracks the Vulkan command currently being used. */
|
/** Tracks the Vulkan command currently being used. */
|
||||||
typedef enum : uint8_t {
|
typedef enum : uint8_t {
|
||||||
kMVKCommandUseNone = 0, /**< No use defined. */
|
kMVKCommandUseNone = 0, /**< No use defined. */
|
||||||
@ -142,7 +145,7 @@ static inline std::string mvkGetMoltenVKVersionString(uint32_t mvkVersion) {
|
|||||||
/** Returns whether the specified positive value is a power-of-two. */
|
/** Returns whether the specified positive value is a power-of-two. */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static constexpr bool mvkIsPowerOfTwo(T value) {
|
static constexpr bool mvkIsPowerOfTwo(T value) {
|
||||||
return value && ((value & (value - 1)) == 0);
|
return value > 0 && ((value & (value - 1)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -278,21 +281,21 @@ void mvkFlipVertically(void* rowMajorData, uint32_t rowCount, size_t bytesPerRow
|
|||||||
* They are ridiculously large numbers, but low enough to be safely used as both
|
* They are ridiculously large numbers, but low enough to be safely used as both
|
||||||
* uint and int values without risking overflowing between positive and negative values.
|
* uint and int values without risking overflowing between positive and negative values.
|
||||||
*/
|
*/
|
||||||
static int32_t kMVKUndefinedLargePositiveInt32 = mvkEnsurePowerOfTwo(std::numeric_limits<int32_t>::max() / 2);
|
static constexpr int32_t kMVKUndefinedLargePositiveInt32 = mvkEnsurePowerOfTwo(std::numeric_limits<int32_t>::max() / 2);
|
||||||
static int32_t kMVKUndefinedLargeNegativeInt32 = -kMVKUndefinedLargePositiveInt32;
|
static constexpr int32_t kMVKUndefinedLargeNegativeInt32 = -kMVKUndefinedLargePositiveInt32;
|
||||||
static uint32_t kMVKUndefinedLargeUInt32 = kMVKUndefinedLargePositiveInt32;
|
static constexpr uint32_t kMVKUndefinedLargeUInt32 = kMVKUndefinedLargePositiveInt32;
|
||||||
static int64_t kMVKUndefinedLargePositiveInt64 = mvkEnsurePowerOfTwo(std::numeric_limits<int64_t>::max() / 2);
|
static constexpr int64_t kMVKUndefinedLargePositiveInt64 = mvkEnsurePowerOfTwo(std::numeric_limits<int64_t>::max() / 2);
|
||||||
static int64_t kMVKUndefinedLargeNegativeInt64 = -kMVKUndefinedLargePositiveInt64;
|
static constexpr int64_t kMVKUndefinedLargeNegativeInt64 = -kMVKUndefinedLargePositiveInt64;
|
||||||
static uint64_t kMVKUndefinedLargeUInt64 = kMVKUndefinedLargePositiveInt64;
|
static constexpr uint64_t kMVKUndefinedLargeUInt64 = kMVKUndefinedLargePositiveInt64;
|
||||||
|
|
||||||
|
|
||||||
#pragma mark Vulkan structure support functions
|
#pragma mark Vulkan structure support functions
|
||||||
|
|
||||||
/** Returns a VkExtent2D created from the width and height of a VkExtent3D. */
|
/** Returns a VkExtent2D created from the width and height of a VkExtent3D. */
|
||||||
static inline VkExtent2D mvkVkExtent2DFromVkExtent3D(VkExtent3D e) { return {e.width, e.height }; }
|
static constexpr VkExtent2D mvkVkExtent2DFromVkExtent3D(VkExtent3D e) { return {e.width, e.height }; }
|
||||||
|
|
||||||
/** Returns a VkExtent3D, created from a VkExtent2D, and with depth of 1. */
|
/** Returns a VkExtent3D, created from a VkExtent2D, and with depth of 1. */
|
||||||
static inline VkExtent3D mvkVkExtent3DFromVkExtent2D(VkExtent2D e) { return {e.width, e.height, 1U }; }
|
static constexpr VkExtent3D mvkVkExtent3DFromVkExtent2D(VkExtent2D e) { return {e.width, e.height, 1U }; }
|
||||||
|
|
||||||
/** Returns whether the two Vulkan extents are equal by comparing their respective components. */
|
/** Returns whether the two Vulkan extents are equal by comparing their respective components. */
|
||||||
static constexpr bool mvkVkExtent2DsAreEqual(VkExtent2D e1, VkExtent2D e2) {
|
static constexpr bool mvkVkExtent2DsAreEqual(VkExtent2D e1, VkExtent2D e2) {
|
||||||
@ -333,13 +336,13 @@ static constexpr uint32_t mvkPackSwizzle(VkComponentMapping components) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Unpacks a single 32-bit word containing four swizzle components. */
|
/** Unpacks a single 32-bit word containing four swizzle components. */
|
||||||
static inline VkComponentMapping mvkUnpackSwizzle(uint32_t packed) {
|
static constexpr VkComponentMapping mvkUnpackSwizzle(uint32_t packed) {
|
||||||
VkComponentMapping components;
|
return {
|
||||||
components.r = (VkComponentSwizzle)((packed >> 0) & 0xFF);
|
.r = (VkComponentSwizzle)((packed >> 0) & 0xFF),
|
||||||
components.g = (VkComponentSwizzle)((packed >> 8) & 0xFF);
|
.g = (VkComponentSwizzle)((packed >> 8) & 0xFF),
|
||||||
components.b = (VkComponentSwizzle)((packed >> 16) & 0xFF);
|
.b = (VkComponentSwizzle)((packed >> 16) & 0xFF),
|
||||||
components.a = (VkComponentSwizzle)((packed >> 24) & 0xFF);
|
.a = (VkComponentSwizzle)((packed >> 24) & 0xFF),
|
||||||
return components;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -384,24 +387,24 @@ static constexpr bool mvkVkComponentMappingsMatch(VkComponentMapping cm1, VkComp
|
|||||||
|
|
||||||
/** Rounds the value to nearest integer using half-to-even rounding. */
|
/** Rounds the value to nearest integer using half-to-even rounding. */
|
||||||
static inline double mvkRoundHalfToEven(const double val) {
|
static inline double mvkRoundHalfToEven(const double val) {
|
||||||
return val - std::remainder(val, 1.0); // remainder() uses half-to-even rounding, and unfortunately isn't constexpr until C++23.
|
return val - std::remainder(val, 1.0); // remainder() uses half-to-even rounding, but unfortunately isn't constexpr until C++23.
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether the value will fit inside the numeric type. */
|
/** Returns whether the value will fit inside the numeric type. */
|
||||||
template<typename T, typename Tval>
|
template<typename T, typename Tval>
|
||||||
const bool mvkFits(const Tval& val) {
|
static constexpr bool mvkFits(const Tval& val) {
|
||||||
return val <= std::numeric_limits<T>::max();
|
return val <= std::numeric_limits<T>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clamps the value between the lower and upper bounds, inclusive. */
|
/** Clamps the value between the lower and upper bounds, inclusive. */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T& mvkClamp(const T& val, const T& lower, const T& upper) {
|
static constexpr const T& mvkClamp(const T& val, const T& lower, const T& upper) {
|
||||||
return std::min(std::max(val, lower), upper);
|
return std::min(std::max(val, lower), upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the result of a division, rounded up. */
|
/** Returns the result of a division, rounded up. */
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
constexpr typename std::common_type<T, U>::type mvkCeilingDivide(T numerator, U denominator) {
|
static constexpr typename std::common_type<T, U>::type mvkCeilingDivide(T numerator, U denominator) {
|
||||||
typedef typename std::common_type<T, U>::type R;
|
typedef typename std::common_type<T, U>::type R;
|
||||||
// Short circuit very common usecase of dividing by one.
|
// Short circuit very common usecase of dividing by one.
|
||||||
return (denominator == 1) ? numerator : (R(numerator) + denominator - 1) / denominator;
|
return (denominator == 1) ? numerator : (R(numerator) + denominator - 1) / denominator;
|
||||||
@ -427,18 +430,18 @@ struct MVKAbs<R, T, false> {
|
|||||||
|
|
||||||
/** Returns the absolute value of the difference of two numbers. */
|
/** Returns the absolute value of the difference of two numbers. */
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
constexpr typename std::common_type<T, U>::type mvkAbsDiff(T x, U y) {
|
static constexpr typename std::common_type<T, U>::type mvkAbsDiff(T x, U y) {
|
||||||
return x >= y ? x - y : y - x;
|
return x >= y ? x - y : y - x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the greatest common divisor of two numbers. */
|
/** Returns the greatest common divisor of two numbers. */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr T mvkGreatestCommonDivisorImpl(T a, T b) {
|
static constexpr T mvkGreatestCommonDivisorImpl(T a, T b) {
|
||||||
return b == 0 ? a : mvkGreatestCommonDivisorImpl(b, a % b);
|
return b == 0 ? a : mvkGreatestCommonDivisorImpl(b, a % b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
constexpr typename std::common_type<T, U>::type mvkGreatestCommonDivisor(T a, U b) {
|
static constexpr typename std::common_type<T, U>::type mvkGreatestCommonDivisor(T a, U b) {
|
||||||
typedef typename std::common_type<T, U>::type R;
|
typedef typename std::common_type<T, U>::type R;
|
||||||
typedef typename std::make_unsigned<R>::type UI;
|
typedef typename std::make_unsigned<R>::type UI;
|
||||||
return static_cast<R>(mvkGreatestCommonDivisorImpl(static_cast<UI>(MVKAbs<R, T>::eval(a)), static_cast<UI>(MVKAbs<R, U>::eval(b))));
|
return static_cast<R>(mvkGreatestCommonDivisorImpl(static_cast<UI>(MVKAbs<R, T>::eval(a)), static_cast<UI>(MVKAbs<R, U>::eval(b))));
|
||||||
@ -446,7 +449,7 @@ constexpr typename std::common_type<T, U>::type mvkGreatestCommonDivisor(T a, U
|
|||||||
|
|
||||||
/** Returns the least common multiple of two numbers. */
|
/** Returns the least common multiple of two numbers. */
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
constexpr typename std::common_type<T, U>::type mvkLeastCommonMultiple(T a, U b) {
|
static constexpr typename std::common_type<T, U>::type mvkLeastCommonMultiple(T a, U b) {
|
||||||
typedef typename std::common_type<T, U>::type R;
|
typedef typename std::common_type<T, U>::type R;
|
||||||
return (a == 0 && b == 0) ? 0 : MVKAbs<R, T>::eval(a) / mvkGreatestCommonDivisor(a, b) * MVKAbs<R, U>::eval(b);
|
return (a == 0 && b == 0) ? 0 : MVKAbs<R, T>::eval(a) / mvkGreatestCommonDivisor(a, b) * MVKAbs<R, U>::eval(b);
|
||||||
}
|
}
|
||||||
@ -463,7 +466,7 @@ constexpr typename std::common_type<T, U>::type mvkLeastCommonMultiple(T a, U b)
|
|||||||
* value returned by previous calls as the seed in subsequent calls.
|
* value returned by previous calls as the seed in subsequent calls.
|
||||||
*/
|
*/
|
||||||
template<class N>
|
template<class N>
|
||||||
std::size_t mvkHash(const N* pVals, std::size_t count = 1, std::size_t seed = 5381) {
|
static constexpr std::size_t mvkHash(const N* pVals, std::size_t count = 1, std::size_t seed = 5381) {
|
||||||
std::size_t hash = seed;
|
std::size_t hash = seed;
|
||||||
for (std::size_t i = 0; i < count; i++) { hash = ((hash << 5) + hash) ^ pVals[i]; }
|
for (std::size_t i = 0; i < count; i++) { hash = ((hash << 5) + hash) ^ pVals[i]; }
|
||||||
return hash;
|
return hash;
|
||||||
@ -497,7 +500,7 @@ protected:
|
|||||||
|
|
||||||
/** Ensures the size of the specified container is at least the specified size. */
|
/** Ensures the size of the specified container is at least the specified size. */
|
||||||
template<typename C, typename S>
|
template<typename C, typename S>
|
||||||
void mvkEnsureSize(C& container, S size) {
|
static void mvkEnsureSize(C& container, S size) {
|
||||||
if (size > container.size()) { container.resize(size); }
|
if (size > container.size()) { container.resize(size); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,7 +509,7 @@ void mvkEnsureSize(C& container, S size) {
|
|||||||
* each object, including freeing the object memory, and clearing the container.
|
* each object, including freeing the object memory, and clearing the container.
|
||||||
*/
|
*/
|
||||||
template<typename C>
|
template<typename C>
|
||||||
void mvkDestroyContainerContents(C& container) {
|
static void mvkDestroyContainerContents(C& container) {
|
||||||
for (auto elem : container) { elem->destroy(); }
|
for (auto elem : container) { elem->destroy(); }
|
||||||
container.clear();
|
container.clear();
|
||||||
}
|
}
|
||||||
@ -517,7 +520,7 @@ void mvkDestroyContainerContents(C& container) {
|
|||||||
*/
|
*/
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
template<typename C>
|
template<typename C>
|
||||||
void mvkReleaseContainerContents(C& container) {
|
static void mvkReleaseContainerContents(C& container) {
|
||||||
for (auto elem : container) { [elem release]; }
|
for (auto elem : container) { [elem release]; }
|
||||||
container.clear();
|
container.clear();
|
||||||
}
|
}
|
||||||
@ -525,14 +528,14 @@ void mvkReleaseContainerContents(C& container) {
|
|||||||
|
|
||||||
/** Returns whether the container contains an item equal to the value. */
|
/** Returns whether the container contains an item equal to the value. */
|
||||||
template<class C, class T>
|
template<class C, class T>
|
||||||
bool mvkContains(C& container, const T& val) {
|
static constexpr bool mvkContains(C& container, const T& val) {
|
||||||
for (const T& cVal : container) { if (cVal == val) { return true; } }
|
for (const T& cVal : container) { if (cVal == val) { return true; } }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes the first occurance of the specified value from the specified container. */
|
/** Removes the first occurance of the specified value from the specified container. */
|
||||||
template<class C, class T>
|
template<class C, class T>
|
||||||
void mvkRemoveFirstOccurance(C& container, T val) {
|
static void mvkRemoveFirstOccurance(C& container, T val) {
|
||||||
for (auto iter = container.begin(), end = container.end(); iter != end; iter++) {
|
for (auto iter = container.begin(), end = container.end(); iter != end; iter++) {
|
||||||
if( *iter == val ) {
|
if( *iter == val ) {
|
||||||
container.erase(iter);
|
container.erase(iter);
|
||||||
@ -543,7 +546,7 @@ void mvkRemoveFirstOccurance(C& container, T val) {
|
|||||||
|
|
||||||
/** Removes all occurances of the specified value from the specified container. */
|
/** Removes all occurances of the specified value from the specified container. */
|
||||||
template<class C, class T>
|
template<class C, class T>
|
||||||
void mvkRemoveAllOccurances(C& container, T val) {
|
static void mvkRemoveAllOccurances(C& container, T val) {
|
||||||
container.erase(std::remove(container.begin(), container.end(), val), container.end());
|
container.erase(std::remove(container.begin(), container.end(), val), container.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,7 +555,7 @@ void mvkRemoveAllOccurances(C& container, T val) {
|
|||||||
|
|
||||||
/** Selects and returns one of the values, based on the platform OS. */
|
/** Selects and returns one of the values, based on the platform OS. */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T& mvkSelectPlatformValue(const T& macOSVal, const T& iOSVal) {
|
static constexpr const T& mvkSelectPlatformValue(const T& macOSVal, const T& iOSVal) {
|
||||||
#if MVK_IOS_OR_TVOS
|
#if MVK_IOS_OR_TVOS
|
||||||
return iOSVal;
|
return iOSVal;
|
||||||
#endif
|
#endif
|
||||||
@ -566,22 +569,29 @@ const T& mvkSelectPlatformValue(const T& macOSVal, const T& iOSVal) {
|
|||||||
* The optional count allows clearing multiple elements in an array.
|
* The optional count allows clearing multiple elements in an array.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void mvkClear(T* pVal, size_t count = 1) { if (pVal) { memset(pVal, 0, sizeof(T) * count); } }
|
static void mvkClear(T* pDst, size_t count = 1) {
|
||||||
|
if ( !pDst ) { return; } // Bad pointer
|
||||||
|
if constexpr(std::is_arithmetic_v<T>) { if (count == 1) { *pDst = static_cast<T>(0); } } // Fast clear of a single primitive
|
||||||
|
memset(pDst, 0, sizeof(T) * count); // Memory clear of complex content or array
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If pVal is not null, overrides the const declaration, and clears the memory occupied by *pVal
|
* If pVal is not null, overrides the const declaration, and clears the memory occupied by *pVal
|
||||||
* by writing zeros to all bytes. The optional count allows clearing multiple elements in an array.
|
* by writing zeros to all bytes. The optional count allows clearing multiple elements in an array.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void mvkClear(const T* pVal, size_t count = 1) { mvkClear((T*)pVal, count); }
|
static void mvkClear(const T* pVal, size_t count = 1) { mvkClear((T*)pVal, count); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If pSrc and pDst are both not null, copies the contents of the source value to the
|
* If pSrc and pDst are both not null, copies the contents of the source value to the
|
||||||
* destination value. The optional count allows copying of multiple elements in an array.
|
* destination value. The optional count allows copying of multiple elements in an array.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void mvkCopy(T* pDst, const T* pSrc, size_t count = 1) {
|
static void mvkCopy(T* pDst, const T* pSrc, size_t count = 1) {
|
||||||
if (pSrc && pDst) { memcpy(pDst, pSrc, sizeof(T) * count); }
|
if ( !pDst || !pSrc ) { return; } // Bad pointers
|
||||||
|
if (pDst == pSrc) { return; } // Same object
|
||||||
|
if constexpr(std::is_arithmetic_v<T>) { if (count == 1) { *pDst = *pSrc; } } // Fast copy of a single primitive
|
||||||
|
memcpy(pDst, pSrc, sizeof(T) * count); // Memory copy of complex content or array
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -589,8 +599,11 @@ void mvkCopy(T* pDst, const T* pSrc, size_t count = 1) {
|
|||||||
* otherwise returns false. The optional count allows comparing multiple elements in an array.
|
* otherwise returns false. The optional count allows comparing multiple elements in an array.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool mvkAreEqual(const T* pV1, const T* pV2, size_t count = 1) {
|
static constexpr bool mvkAreEqual(const T* pV1, const T* pV2, size_t count = 1) {
|
||||||
return (pV1 && pV2) ? (memcmp(pV1, pV2, sizeof(T) * count) == 0) : false;
|
if ( !pV2 || !pV2 ) { return false; } // Bad pointers
|
||||||
|
if (pV1 == pV2) { return true; } // Same object
|
||||||
|
if constexpr(std::is_arithmetic_v<T>) { if (count == 1) { return *pV1 == *pV2; } } // Fast compare of a single primitive
|
||||||
|
return memcmp(pV1, pV2, sizeof(T) * count) == 0; // Memory compare of complex content or array
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -632,10 +645,18 @@ static constexpr bool mvkSetOrClear(T* pDest, const T* pSrc) {
|
|||||||
template<typename Tv, typename Tm>
|
template<typename Tv, typename Tm>
|
||||||
void mvkEnableFlags(Tv& value, const Tm bitMask) { value = (Tv)(value | bitMask); }
|
void mvkEnableFlags(Tv& value, const Tm bitMask) { value = (Tv)(value | bitMask); }
|
||||||
|
|
||||||
|
/** Enables all the flags (sets bits to 1) within the value parameter. */
|
||||||
|
template<typename Tv>
|
||||||
|
void mvkEnableAllFlags(Tv& value) { value = ~static_cast<Tv>(0); }
|
||||||
|
|
||||||
/** Disables the flags (sets bits to 0) within the value parameter specified by the bitMask parameter. */
|
/** Disables the flags (sets bits to 0) within the value parameter specified by the bitMask parameter. */
|
||||||
template<typename Tv, typename Tm>
|
template<typename Tv, typename Tm>
|
||||||
void mvkDisableFlags(Tv& value, const Tm bitMask) { value = (Tv)(value & ~(Tv)bitMask); }
|
void mvkDisableFlags(Tv& value, const Tm bitMask) { value = (Tv)(value & ~(Tv)bitMask); }
|
||||||
|
|
||||||
|
/** Enables all the flags (sets bits to 1) within the value parameter. */
|
||||||
|
template<typename Tv>
|
||||||
|
void mvkDisableAllFlags(Tv& value) { value = static_cast<Tv>(0); }
|
||||||
|
|
||||||
/** Returns whether the specified value has ANY of the flags specified in bitMask enabled (set to 1). */
|
/** Returns whether the specified value has ANY of the flags specified in bitMask enabled (set to 1). */
|
||||||
template<typename Tv, typename Tm>
|
template<typename Tv, typename Tm>
|
||||||
static constexpr bool mvkIsAnyFlagEnabled(Tv value, const Tm bitMask) { return ((value & bitMask) != 0); }
|
static constexpr bool mvkIsAnyFlagEnabled(Tv value, const Tm bitMask) { return ((value & bitMask) != 0); }
|
||||||
|
@ -584,23 +584,32 @@ MTLMultisampleStencilResolveFilter mvkMTLMultisampleStencilResolveFilterFromVkRe
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
MVK_PUBLIC_SYMBOL MTLViewport mvkMTLViewportFromVkViewport(VkViewport vkViewport) {
|
MVK_PUBLIC_SYMBOL MTLViewport mvkMTLViewportFromVkViewport(VkViewport vkViewport) {
|
||||||
MTLViewport mtlViewport;
|
return {
|
||||||
mtlViewport.originX = vkViewport.x;
|
.originX = vkViewport.x,
|
||||||
mtlViewport.originY = vkViewport.y;
|
.originY = vkViewport.y,
|
||||||
mtlViewport.width = vkViewport.width;
|
.width = vkViewport.width,
|
||||||
mtlViewport.height = vkViewport.height;
|
.height = vkViewport.height,
|
||||||
mtlViewport.znear = vkViewport.minDepth;
|
.znear = vkViewport.minDepth,
|
||||||
mtlViewport.zfar = vkViewport.maxDepth;
|
.zfar = vkViewport.maxDepth
|
||||||
return mtlViewport;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_SYMBOL MTLScissorRect mvkMTLScissorRectFromVkRect2D(VkRect2D vkRect) {
|
MVK_PUBLIC_SYMBOL MTLScissorRect mvkMTLScissorRectFromVkRect2D(VkRect2D vkRect) {
|
||||||
MTLScissorRect mtlScissor;
|
return {
|
||||||
mtlScissor.x = vkRect.offset.x;
|
.x = (NSUInteger)max(vkRect.offset.x, 0),
|
||||||
mtlScissor.y = vkRect.offset.y;
|
.y = (NSUInteger)max(vkRect.offset.y, 0),
|
||||||
mtlScissor.width = vkRect.extent.width;
|
.width = vkRect.extent.width,
|
||||||
mtlScissor.height = vkRect.extent.height;
|
.height = vkRect.extent.height
|
||||||
return mtlScissor;
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_SYMBOL VkRect2D mvkVkRect2DFromMTLScissorRect(MTLScissorRect mtlScissorRect) {
|
||||||
|
return {
|
||||||
|
.offset = { .x = (int32_t)mtlScissorRect.x,
|
||||||
|
.y = (int32_t)mtlScissorRect.y },
|
||||||
|
.extent = { .width = (uint32_t)mtlScissorRect.width,
|
||||||
|
.height = (uint32_t)mtlScissorRect.height }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_SYMBOL MTLCompareFunction mvkMTLCompareFunctionFromVkCompareOp(VkCompareOp vkOp) {
|
MVK_PUBLIC_SYMBOL MTLCompareFunction mvkMTLCompareFunctionFromVkCompareOp(VkCompareOp vkOp) {
|
||||||
|
@ -1466,7 +1466,6 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetLineWidth(
|
|||||||
float lineWidth) {
|
float lineWidth) {
|
||||||
|
|
||||||
MVKTraceVulkanCallStart();
|
MVKTraceVulkanCallStart();
|
||||||
MVKAddCmd(SetLineWidth, commandBuffer, lineWidth);
|
|
||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1496,7 +1495,6 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBounds(
|
|||||||
float maxDepthBounds) {
|
float maxDepthBounds) {
|
||||||
|
|
||||||
MVKTraceVulkanCallStart();
|
MVKTraceVulkanCallStart();
|
||||||
MVKAddCmd(SetDepthBounds, commandBuffer, minDepthBounds, maxDepthBounds);
|
|
||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1564,13 +1562,14 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBindIndexBuffer(
|
|||||||
|
|
||||||
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBindVertexBuffers(
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBindVertexBuffers(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
uint32_t startBinding,
|
uint32_t firstBinding,
|
||||||
uint32_t bindingCount,
|
uint32_t bindingCount,
|
||||||
const VkBuffer* pBuffers,
|
const VkBuffer* pBuffers,
|
||||||
const VkDeviceSize* pOffsets) {
|
const VkDeviceSize* pOffsets) {
|
||||||
|
|
||||||
MVKTraceVulkanCallStart();
|
MVKTraceVulkanCallStart();
|
||||||
MVKAddCmdFrom2Thresholds(BindVertexBuffers, bindingCount, 1, 2, commandBuffer, startBinding, bindingCount, pBuffers, pOffsets);
|
MVKAddCmdFrom2Thresholds(BindVertexBuffers, bindingCount, 1, 2, commandBuffer,
|
||||||
|
firstBinding, bindingCount, pBuffers, pOffsets, nullptr, nullptr);
|
||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2526,16 +2525,21 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBeginRendering(
|
|||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdEndRendering(
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBindVertexBuffers2(
|
||||||
VkCommandBuffer commandBuffer) {
|
VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t firstBinding,
|
||||||
|
uint32_t bindingCount,
|
||||||
|
const VkBuffer* pBuffers,
|
||||||
|
const VkDeviceSize* pOffsets,
|
||||||
|
const VkDeviceSize* pSizes,
|
||||||
|
const VkDeviceSize* pStrides) {
|
||||||
|
|
||||||
MVKTraceVulkanCallStart();
|
MVKTraceVulkanCallStart();
|
||||||
MVKAddCmd(EndRendering, commandBuffer);
|
MVKAddCmdFrom2Thresholds(BindVertexBuffers, bindingCount, 1, 2, commandBuffer,
|
||||||
|
firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides);
|
||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdBindVertexBuffers2, void, VkCommandBuffer, uint32_t, uint32_t, const VkBuffer*, const VkDeviceSize*, const VkDeviceSize*, const VkDeviceSize*)
|
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBlitImage2(
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBlitImage2(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
const VkBlitImageInfo2* pBlitImageInfo) {
|
const VkBlitImageInfo2* pBlitImageInfo) {
|
||||||
@ -2585,6 +2589,14 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyImageToBuffer2(
|
|||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdEndRendering(
|
||||||
|
VkCommandBuffer commandBuffer) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(EndRendering, commandBuffer);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdPipelineBarrier2(
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdPipelineBarrier2(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
const VkDependencyInfo* pDependencyInfo) {
|
const VkDependencyInfo* pDependencyInfo) {
|
||||||
@ -2615,12 +2627,58 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdResolveImage2(
|
|||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetCullMode, void, VkCommandBuffer, VkCullModeFlags)
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetCullMode(
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetDepthBiasEnable, void, VkCommandBuffer, VkBool32)
|
VkCommandBuffer commandBuffer,
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetDepthBoundsTestEnable, void, VkCommandBuffer, VkBool32)
|
VkCullModeFlags cullMode) {
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetDepthCompareOp, void, VkCommandBuffer, VkCompareOp)
|
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetDepthTestEnable, void, VkCommandBuffer, VkBool32)
|
MVKTraceVulkanCallStart();
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetDepthWriteEnable, void, VkCommandBuffer, VkBool32)
|
MVKAddCmd(SetCullMode, commandBuffer, cullMode);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBiasEnable(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkBool32 depthBiasEnable) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetDepthBiasEnable, commandBuffer, depthBiasEnable);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthBoundsTestEnable(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkBool32 depthBoundsTestEnable) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthCompareOp(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkCompareOp depthCompareOp) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetDepthCompareOp, commandBuffer, depthCompareOp);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthTestEnable(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkBool32 depthTestEnable) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetDepthTestEnable, commandBuffer, depthTestEnable);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetDepthWriteEnable(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkBool32 depthWriteEnable) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetDepthWriteEnable, commandBuffer, depthWriteEnable);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetEvent2(
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetEvent2(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
@ -2632,14 +2690,83 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetEvent2(
|
|||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetFrontFace, void, VkCommandBuffer, VkFrontFace)
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetFrontFace(
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetPrimitiveRestartEnable, void, VkCommandBuffer, VkBool32)
|
VkCommandBuffer commandBuffer,
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetPrimitiveTopology, void, VkCommandBuffer, VkPrimitiveTopology)
|
VkFrontFace frontFace) {
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetRasterizerDiscardEnable, void, VkCommandBuffer, VkBool32)
|
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetScissorWithCount, void, VkCommandBuffer, uint32_t, const VkRect2D*)
|
MVKTraceVulkanCallStart();
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetStencilOp, void, VkCommandBuffer, VkStencilFaceFlags, VkStencilOp, VkStencilOp, VkStencilOp, VkCompareOp)
|
MVKAddCmd(SetFrontFace, commandBuffer, frontFace);
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetStencilTestEnable, void, VkCommandBuffer, VkBool32)
|
MVKTraceVulkanCallEnd();
|
||||||
MVK_PUBLIC_VULKAN_STUB(vkCmdSetViewportWithCount, void, VkCommandBuffer, uint32_t, const VkViewport*)
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetPrimitiveRestartEnable(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkBool32 primitiveRestartEnable) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetPrimitiveRestartEnable, commandBuffer, primitiveRestartEnable);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetPrimitiveTopology(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkPrimitiveTopology primitiveTopology) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetPrimitiveTopology, commandBuffer, primitiveTopology);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetRasterizerDiscardEnable(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkBool32 rasterizerDiscardEnable) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetRasterizerDiscardEnable, commandBuffer, rasterizerDiscardEnable);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetScissorWithCount(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t scissorCount,
|
||||||
|
const VkRect2D* pScissors) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmdFromThreshold(SetScissor, scissorCount, 1, commandBuffer, 0, scissorCount, pScissors);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetStencilOp(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkStencilFaceFlags faceMask,
|
||||||
|
VkStencilOp failOp,
|
||||||
|
VkStencilOp passOp,
|
||||||
|
VkStencilOp depthFailOp,
|
||||||
|
VkCompareOp compareOp) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetStencilOp, commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetStencilTestEnable(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
VkBool32 stencilTestEnable) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmd(SetStencilTestEnable, commandBuffer, stencilTestEnable);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdSetViewportWithCount(
|
||||||
|
VkCommandBuffer commandBuffer,
|
||||||
|
uint32_t viewportCount,
|
||||||
|
const VkViewport* pViewports) {
|
||||||
|
|
||||||
|
MVKTraceVulkanCallStart();
|
||||||
|
MVKAddCmdFromThreshold(SetViewport, viewportCount, 1, commandBuffer, 0, viewportCount, pViewports);
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdWaitEvents2(
|
MVK_PUBLIC_VULKAN_SYMBOL void vkCmdWaitEvents2(
|
||||||
VkCommandBuffer commandBuffer,
|
VkCommandBuffer commandBuffer,
|
||||||
@ -2733,7 +2860,6 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkSetPrivateData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark VK_KHR_bind_memory2 extension
|
#pragma mark VK_KHR_bind_memory2 extension
|
||||||
|
|
||||||
@ -3481,6 +3607,60 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkSubmitDebugUtilsMessageEXT(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark VK_EXT_extended_dynamic_state
|
||||||
|
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdBindVertexBuffers2, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetCullMode, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetDepthBoundsTestEnable, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetDepthCompareOp, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetDepthTestEnable, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetDepthWriteEnable, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetFrontFace, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetPrimitiveTopology, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetScissorWithCount, EXT);
|
||||||
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdSetStencilOp, EXT);
|
||||||
|
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();
|
||||||
|
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();
|
||||||
|
MVKTraceVulkanCallEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark VK_EXT_external_memory_host extension
|
#pragma mark VK_EXT_external_memory_host extension
|
||||||
|
|
||||||
@ -3565,6 +3745,7 @@ MVK_PUBLIC_VULKAN_CORE_ALIAS(vkGetPrivateData, EXT);
|
|||||||
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkSetPrivateData, EXT);
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkSetPrivateData, EXT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark VK_EXT_sample_locations extension
|
#pragma mark VK_EXT_sample_locations extension
|
||||||
|
|
||||||
@ -3588,6 +3769,7 @@ void vkCmdSetSampleLocationsEXT(
|
|||||||
MVKTraceVulkanCallEnd();
|
MVKTraceVulkanCallEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark VK_GOOGLE_display_timing extension
|
#pragma mark VK_GOOGLE_display_timing extension
|
||||||
|
|
||||||
@ -3616,12 +3798,14 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkGetPastPresentationTimingGOOGLE(
|
|||||||
return rslt;
|
return rslt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark VK_AMD_draw_indirect_count
|
#pragma mark VK_AMD_draw_indirect_count
|
||||||
|
|
||||||
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdDrawIndexedIndirectCount, AMD);
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdDrawIndexedIndirectCount, AMD);
|
||||||
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdDrawIndirectCount, AMD);
|
MVK_PUBLIC_VULKAN_CORE_ALIAS(vkCmdDrawIndirectCount, AMD);
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark iOS & macOS surface extensions
|
#pragma mark iOS & macOS surface extensions
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user