shader: Implement ViewportIndex
This commit is contained in:
		| @@ -509,6 +509,12 @@ void EmitContext::DefineOutputs(const Info& info) { | ||||
|         const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; | ||||
|         clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); | ||||
|     } | ||||
|     if (info.stores_viewport_index && !ignore_viewport_layer) { | ||||
|         if (stage == Stage::Fragment) { | ||||
|             throw NotImplementedException("Storing ViewportIndex in Fragment stage"); | ||||
|         } | ||||
|         viewport_index = DefineOutput(*this, U32[1], spv::BuiltIn::ViewportIndex); | ||||
|     } | ||||
|     for (size_t i = 0; i < info.stores_generics.size(); ++i) { | ||||
|         if (info.stores_generics[i]) { | ||||
|             output_generics[i] = DefineOutput(*this, F32[4]); | ||||
|   | ||||
| @@ -106,6 +106,7 @@ public: | ||||
|     Id front_face{}; | ||||
|     Id point_coord{}; | ||||
|     Id clip_distances{}; | ||||
|     Id viewport_index{}; | ||||
|  | ||||
|     Id fswzadd_lut_a{}; | ||||
|     Id fswzadd_lut_b{}; | ||||
| @@ -133,6 +134,8 @@ public: | ||||
|  | ||||
|     std::vector<Id> interfaces; | ||||
|  | ||||
|     bool ignore_viewport_layer{}; | ||||
|  | ||||
| private: | ||||
|     void DefineCommonTypes(const Info& info); | ||||
|     void DefineCommonConstants(); | ||||
|   | ||||
| @@ -225,6 +225,16 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct | ||||
|         ctx.AddExtension("SPV_EXT_demote_to_helper_invocation"); | ||||
|         ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT); | ||||
|     } | ||||
|     if (info.stores_viewport_index) { | ||||
|         ctx.AddCapability(spv::Capability::MultiViewport); | ||||
|         if (profile.support_viewport_index_layer_non_geometry && | ||||
|             ctx.stage == Shader::Stage::VertexB) { | ||||
|             ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); | ||||
|             ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); | ||||
|         } else { | ||||
|             ctx.ignore_viewport_layer = true; | ||||
|         } | ||||
|     } | ||||
|     if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) { | ||||
|         ctx.AddExtension("SPV_KHR_shader_draw_parameters"); | ||||
|         ctx.AddCapability(spv::Capability::DrawParameters); | ||||
|   | ||||
| @@ -29,7 +29,7 @@ std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { | ||||
|     throw InvalidArgument("Invalid attribute type {}", type); | ||||
| } | ||||
|  | ||||
| Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | ||||
| std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | ||||
|     const u32 element{static_cast<u32>(attr) % 4}; | ||||
|     const auto element_id{[&] { return ctx.Constant(ctx.U32[1], element); }}; | ||||
|     if (IR::IsGeneric(attr)) { | ||||
| @@ -57,6 +57,8 @@ Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | ||||
|         const Id clip_num{ctx.Constant(ctx.U32[1], index)}; | ||||
|         return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); | ||||
|     } | ||||
|     case IR::Attribute::ViewportIndex: | ||||
|         return ctx.ignore_viewport_layer ? std::nullopt : std::optional<Id>{ctx.viewport_index}; | ||||
|     default: | ||||
|         throw NotImplementedException("Read attribute {}", attr); | ||||
|     } | ||||
| @@ -204,7 +206,11 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr) { | ||||
| } | ||||
|  | ||||
| void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value) { | ||||
|     ctx.OpStore(OutputAttrPointer(ctx, attr), value); | ||||
|     auto output = OutputAttrPointer(ctx, attr); | ||||
|     if (!output) { | ||||
|         return; | ||||
|     } | ||||
|     ctx.OpStore(*output, value); | ||||
| } | ||||
|  | ||||
| void EmitGetAttributeIndexed(EmitContext&) { | ||||
|   | ||||
| @@ -81,6 +81,9 @@ void SetAttribute(Info& info, IR::Attribute attribute) { | ||||
|     case IR::Attribute::ClipDistance7: | ||||
|         info.stores_clip_distance = true; | ||||
|         break; | ||||
|     case IR::Attribute::ViewportIndex: | ||||
|         info.stores_viewport_index = true; | ||||
|         break; | ||||
|     default: | ||||
|         throw NotImplementedException("Set attribute {}", attribute); | ||||
|     } | ||||
|   | ||||
| @@ -35,6 +35,7 @@ struct Profile { | ||||
|     bool support_fp64_signed_zero_nan_preserve{}; | ||||
|     bool support_explicit_workgroup_layout{}; | ||||
|     bool support_vote{}; | ||||
|     bool support_viewport_index_layer_non_geometry{}; | ||||
|     bool warp_size_potentially_larger_than_guest{}; | ||||
|  | ||||
|     // FClamp is broken and OpFMax + OpFMin should be used instead | ||||
|   | ||||
| @@ -82,6 +82,7 @@ struct Info { | ||||
|     bool stores_position{}; | ||||
|     bool stores_point_size{}; | ||||
|     bool stores_clip_distance{}; | ||||
|     bool stores_viewport_index{}; | ||||
|  | ||||
|     bool uses_fp16{}; | ||||
|     bool uses_fp64{}; | ||||
|   | ||||
| @@ -631,6 +631,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::GPU& gpu_, | ||||
|             float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE, | ||||
|         .support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(), | ||||
|         .support_vote = true, | ||||
|         .support_viewport_index_layer_non_geometry = device.IsExtShaderViewportIndexLayerSupported(), | ||||
|         .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), | ||||
|         .has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR, | ||||
|         .generic_input_types{}, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 FernandoS27
					FernandoS27