spirv: Implement ViewportMask with NV_viewport_array2
This commit is contained in:
		| @@ -457,6 +457,7 @@ void EmitContext::DefineCommonTypes(const Info& info) { | |||||||
|     input_s32 = Name(TypePointer(spv::StorageClass::Input, TypeInt(32, true)), "input_s32"); |     input_s32 = Name(TypePointer(spv::StorageClass::Input, TypeInt(32, true)), "input_s32"); | ||||||
|  |  | ||||||
|     output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32"); |     output_f32 = Name(TypePointer(spv::StorageClass::Output, F32[1]), "output_f32"); | ||||||
|  |     output_u32 = Name(TypePointer(spv::StorageClass::Output, U32[1]), "output_u32"); | ||||||
|  |  | ||||||
|     if (info.uses_int8) { |     if (info.uses_int8) { | ||||||
|         AddCapability(spv::Capability::Int8); |         AddCapability(spv::Capability::Int8); | ||||||
| @@ -1131,6 +1132,9 @@ void EmitContext::DefineOutputs(const IR::Program& program) { | |||||||
|         } |         } | ||||||
|         viewport_index = DefineOutput(*this, U32[1], invocations, spv::BuiltIn::ViewportIndex); |         viewport_index = DefineOutput(*this, U32[1], invocations, spv::BuiltIn::ViewportIndex); | ||||||
|     } |     } | ||||||
|  |     if (info.stores_viewport_mask && profile.support_viewport_mask) { | ||||||
|  |         viewport_mask = DefineOutput(*this, TypeArray(U32[1], Constant(U32[1], 1u)), std::nullopt); | ||||||
|  |     } | ||||||
|     for (size_t index = 0; index < info.stores_generics.size(); ++index) { |     for (size_t index = 0; index < info.stores_generics.size(); ++index) { | ||||||
|         if (info.stores_generics[index]) { |         if (info.stores_generics[index]) { | ||||||
|             DefineGenericOutput(*this, index, invocations); |             DefineGenericOutput(*this, index, invocations); | ||||||
|   | |||||||
| @@ -134,6 +134,7 @@ public: | |||||||
|     Id input_s32{}; |     Id input_s32{}; | ||||||
|  |  | ||||||
|     Id output_f32{}; |     Id output_f32{}; | ||||||
|  |     Id output_u32{}; | ||||||
|  |  | ||||||
|     Id image_buffer_type{}; |     Id image_buffer_type{}; | ||||||
|     Id sampled_texture_buffer_type{}; |     Id sampled_texture_buffer_type{}; | ||||||
| @@ -167,6 +168,7 @@ public: | |||||||
|     Id clip_distances{}; |     Id clip_distances{}; | ||||||
|     Id layer{}; |     Id layer{}; | ||||||
|     Id viewport_index{}; |     Id viewport_index{}; | ||||||
|  |     Id viewport_mask{}; | ||||||
|     Id primitive_id{}; |     Id primitive_id{}; | ||||||
|  |  | ||||||
|     Id fswzadd_lut_a{}; |     Id fswzadd_lut_a{}; | ||||||
|   | |||||||
| @@ -303,6 +303,10 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct | |||||||
|     if (info.stores_viewport_index) { |     if (info.stores_viewport_index) { | ||||||
|         ctx.AddCapability(spv::Capability::MultiViewport); |         ctx.AddCapability(spv::Capability::MultiViewport); | ||||||
|     } |     } | ||||||
|  |     if (info.stores_viewport_mask && profile.support_viewport_mask) { | ||||||
|  |         ctx.AddExtension("SPV_NV_viewport_array2"); | ||||||
|  |         ctx.AddCapability(spv::Capability::ShaderViewportMaskNV); | ||||||
|  |     } | ||||||
|     if (info.stores_layer || info.stores_viewport_index) { |     if (info.stores_layer || info.stores_viewport_index) { | ||||||
|         if (profile.support_viewport_index_layer_non_geometry && ctx.stage != Stage::Geometry) { |         if (profile.support_viewport_index_layer_non_geometry && ctx.stage != Stage::Geometry) { | ||||||
|             ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); |             ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); | ||||||
|   | |||||||
| @@ -99,6 +99,11 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | |||||||
|                        ctx.stage == Shader::Stage::Geometry |                        ctx.stage == Shader::Stage::Geometry | ||||||
|                    ? std::optional<Id>{ctx.viewport_index} |                    ? std::optional<Id>{ctx.viewport_index} | ||||||
|                    : std::nullopt; |                    : std::nullopt; | ||||||
|  |     case IR::Attribute::ViewportMask: | ||||||
|  |         if (!ctx.profile.support_viewport_mask) { | ||||||
|  |             return std::nullopt; | ||||||
|  |         } | ||||||
|  |         return ctx.OpAccessChain(ctx.output_u32, ctx.viewport_mask, ctx.u32_zero_value); | ||||||
|     default: |     default: | ||||||
|         throw NotImplementedException("Read attribute {}", attr); |         throw NotImplementedException("Read attribute {}", attr); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -96,6 +96,9 @@ void SetAttribute(Info& info, IR::Attribute attribute) { | |||||||
|     case IR::Attribute::ViewportIndex: |     case IR::Attribute::ViewportIndex: | ||||||
|         info.stores_viewport_index = true; |         info.stores_viewport_index = true; | ||||||
|         break; |         break; | ||||||
|  |     case IR::Attribute::ViewportMask: | ||||||
|  |         info.stores_viewport_mask = true; | ||||||
|  |         break; | ||||||
|     default: |     default: | ||||||
|         throw NotImplementedException("Set attribute {}", attribute); |         throw NotImplementedException("Set attribute {}", attribute); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -75,6 +75,7 @@ struct Profile { | |||||||
|     bool support_explicit_workgroup_layout{}; |     bool support_explicit_workgroup_layout{}; | ||||||
|     bool support_vote{}; |     bool support_vote{}; | ||||||
|     bool support_viewport_index_layer_non_geometry{}; |     bool support_viewport_index_layer_non_geometry{}; | ||||||
|  |     bool support_viewport_mask{}; | ||||||
|     bool support_typeless_image_loads{}; |     bool support_typeless_image_loads{}; | ||||||
|     bool warp_size_potentially_larger_than_guest{}; |     bool warp_size_potentially_larger_than_guest{}; | ||||||
|     bool support_int64_atomics{}; |     bool support_int64_atomics{}; | ||||||
|   | |||||||
| @@ -124,6 +124,7 @@ struct Info { | |||||||
|     bool stores_clip_distance{}; |     bool stores_clip_distance{}; | ||||||
|     bool stores_layer{}; |     bool stores_layer{}; | ||||||
|     bool stores_viewport_index{}; |     bool stores_viewport_index{}; | ||||||
|  |     bool stores_viewport_mask{}; | ||||||
|     bool stores_tess_level_outer{}; |     bool stores_tess_level_outer{}; | ||||||
|     bool stores_tess_level_inner{}; |     bool stores_tess_level_inner{}; | ||||||
|     bool stores_indexed_attributes{}; |     bool stores_indexed_attributes{}; | ||||||
|   | |||||||
| @@ -690,6 +690,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::GPU& gpu_, | |||||||
|         .support_vote = true, |         .support_vote = true, | ||||||
|         .support_viewport_index_layer_non_geometry = |         .support_viewport_index_layer_non_geometry = | ||||||
|             device.IsExtShaderViewportIndexLayerSupported(), |             device.IsExtShaderViewportIndexLayerSupported(), | ||||||
|  |         .support_viewport_mask = device.IsNvViewportArray2Supported(), | ||||||
|         .support_typeless_image_loads = device.IsFormatlessImageLoadSupported(), |         .support_typeless_image_loads = device.IsFormatlessImageLoadSupported(), | ||||||
|         .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), |         .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), | ||||||
|         .support_int64_atomics = device.IsExtShaderAtomicInt64Supported(), |         .support_int64_atomics = device.IsExtShaderAtomicInt64Supported(), | ||||||
|   | |||||||
| @@ -346,6 +346,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||||||
|         LOG_INFO(Render_Vulkan, "Device doesn't support viewport swizzles"); |         LOG_INFO(Render_Vulkan, "Device doesn't support viewport swizzles"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (!nv_viewport_array2) { | ||||||
|  |         LOG_INFO(Render_Vulkan, "Device doesn't support viewport masks"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout; |     VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout; | ||||||
|     if (khr_uniform_buffer_standard_layout) { |     if (khr_uniform_buffer_standard_layout) { | ||||||
|         std430_layout = { |         std430_layout = { | ||||||
| @@ -724,6 +728,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|         test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true); |         test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true); | ||||||
|  |         test(nv_viewport_array2, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME, true); | ||||||
|         test(khr_uniform_buffer_standard_layout, |         test(khr_uniform_buffer_standard_layout, | ||||||
|              VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); |              VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); | ||||||
|         test(khr_spirv_1_4, VK_KHR_SPIRV_1_4_EXTENSION_NAME, true); |         test(khr_spirv_1_4, VK_KHR_SPIRV_1_4_EXTENSION_NAME, true); | ||||||
|   | |||||||
| @@ -169,6 +169,11 @@ public: | |||||||
|         return nv_viewport_swizzle; |         return nv_viewport_swizzle; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Returns true if the device supports VK_NV_viewport_array2. | ||||||
|  |     bool IsNvViewportArray2Supported() const { | ||||||
|  |         return nv_viewport_array2; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// Returns true if the device supports VK_KHR_uniform_buffer_standard_layout. |     /// Returns true if the device supports VK_KHR_uniform_buffer_standard_layout. | ||||||
|     bool IsKhrUniformBufferStandardLayoutSupported() const { |     bool IsKhrUniformBufferStandardLayoutSupported() const { | ||||||
|         return khr_uniform_buffer_standard_layout; |         return khr_uniform_buffer_standard_layout; | ||||||
| @@ -312,6 +317,7 @@ private: | |||||||
|     bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images. |     bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images. | ||||||
|     bool is_blit_depth_stencil_supported{};     ///< Support for blitting from and to depth stencil. |     bool is_blit_depth_stencil_supported{};     ///< Support for blitting from and to depth stencil. | ||||||
|     bool nv_viewport_swizzle{};                 ///< Support for VK_NV_viewport_swizzle. |     bool nv_viewport_swizzle{};                 ///< Support for VK_NV_viewport_swizzle. | ||||||
|  |     bool nv_viewport_array2{};                  ///< Support for VK_NV_viewport_array2. | ||||||
|     bool khr_uniform_buffer_standard_layout{};  ///< Support for scalar uniform buffer layouts. |     bool khr_uniform_buffer_standard_layout{};  ///< Support for scalar uniform buffer layouts. | ||||||
|     bool khr_spirv_1_4{};                       ///< Support for VK_KHR_spirv_1_4. |     bool khr_spirv_1_4{};                       ///< Support for VK_KHR_spirv_1_4. | ||||||
|     bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts. |     bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user