shader: Implement SR_Y_DIRECTION
This commit is contained in:
		| @@ -72,6 +72,7 @@ Id EmitLocalInvocationId(EmitContext& ctx); | |||||||
| Id EmitInvocationId(EmitContext& ctx); | Id EmitInvocationId(EmitContext& ctx); | ||||||
| Id EmitSampleId(EmitContext& ctx); | Id EmitSampleId(EmitContext& ctx); | ||||||
| Id EmitIsHelperInvocation(EmitContext& ctx); | Id EmitIsHelperInvocation(EmitContext& ctx); | ||||||
|  | Id EmitYDirection(EmitContext& ctx); | ||||||
| Id EmitLoadLocal(EmitContext& ctx, Id word_offset); | Id EmitLoadLocal(EmitContext& ctx, Id word_offset); | ||||||
| void EmitWriteLocal(EmitContext& ctx, Id word_offset, Id value); | void EmitWriteLocal(EmitContext& ctx, Id word_offset, Id value); | ||||||
| Id EmitUndefU1(EmitContext& ctx); | Id EmitUndefU1(EmitContext& ctx); | ||||||
|   | |||||||
| @@ -403,6 +403,13 @@ Id EmitIsHelperInvocation(EmitContext& ctx) { | |||||||
|     return ctx.OpLoad(ctx.U1, ctx.is_helper_invocation); |     return ctx.OpLoad(ctx.U1, ctx.is_helper_invocation); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | Id EmitYDirection(EmitContext& ctx) { | ||||||
|  |     if (ctx.profile.y_negate) { | ||||||
|  |         return ctx.Constant(ctx.F32[1], -1.0f); | ||||||
|  |     } | ||||||
|  |     return ctx.Constant(ctx.F32[1], 1.0f); | ||||||
|  | } | ||||||
|  |  | ||||||
| Id EmitLoadLocal(EmitContext& ctx, Id word_offset) { | Id EmitLoadLocal(EmitContext& ctx, Id word_offset) { | ||||||
|     const Id pointer{ctx.OpAccessChain(ctx.private_u32, ctx.local_memory, word_offset)}; |     const Id pointer{ctx.OpAccessChain(ctx.private_u32, ctx.local_memory, word_offset)}; | ||||||
|     return ctx.OpLoad(ctx.U32[1], pointer); |     return ctx.OpLoad(ctx.U32[1], pointer); | ||||||
|   | |||||||
| @@ -379,6 +379,10 @@ U1 IREmitter::IsHelperInvocation() { | |||||||
|     return Inst<U1>(Opcode::IsHelperInvocation); |     return Inst<U1>(Opcode::IsHelperInvocation); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | F32 IREmitter::YDirection() { | ||||||
|  |     return Inst<F32>(Opcode::YDirection); | ||||||
|  | } | ||||||
|  |  | ||||||
| U32 IREmitter::LaneId() { | U32 IREmitter::LaneId() { | ||||||
|     return Inst<U32>(Opcode::LaneId); |     return Inst<U32>(Opcode::LaneId); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -102,6 +102,7 @@ public: | |||||||
|     [[nodiscard]] U32 InvocationId(); |     [[nodiscard]] U32 InvocationId(); | ||||||
|     [[nodiscard]] U32 SampleId(); |     [[nodiscard]] U32 SampleId(); | ||||||
|     [[nodiscard]] U1 IsHelperInvocation(); |     [[nodiscard]] U1 IsHelperInvocation(); | ||||||
|  |     [[nodiscard]] F32 YDirection(); | ||||||
|  |  | ||||||
|     [[nodiscard]] U32 LaneId(); |     [[nodiscard]] U32 LaneId(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -65,6 +65,7 @@ OPCODE(LocalInvocationId,                                   U32x3, | |||||||
| OPCODE(InvocationId,                                        U32,                                                                                            ) | OPCODE(InvocationId,                                        U32,                                                                                            ) | ||||||
| OPCODE(SampleId,                                            U32,                                                                                            ) | OPCODE(SampleId,                                            U32,                                                                                            ) | ||||||
| OPCODE(IsHelperInvocation,                                  U1,                                                                                             ) | OPCODE(IsHelperInvocation,                                  U1,                                                                                             ) | ||||||
|  | OPCODE(YDirection,                                          F32,                                                                                            ) | ||||||
|  |  | ||||||
| // Undefined | // Undefined | ||||||
| OPCODE(UndefU1,                                             U1,                                                                                             ) | OPCODE(UndefU1,                                             U1,                                                                                             ) | ||||||
|   | |||||||
| @@ -150,6 +150,8 @@ enum class SpecialRegister : u64 { | |||||||
|         return ir.SubgroupGtMask(); |         return ir.SubgroupGtMask(); | ||||||
|     case SpecialRegister::SR_GEMASK: |     case SpecialRegister::SR_GEMASK: | ||||||
|         return ir.SubgroupGeMask(); |         return ir.SubgroupGeMask(); | ||||||
|  |     case SpecialRegister::SR_Y_DIRECTION: | ||||||
|  |         return ir.BitCast<IR::U32>(ir.YDirection()); | ||||||
|     default: |     default: | ||||||
|         throw NotImplementedException("S2R special register {}", special_register); |         throw NotImplementedException("S2R special register {}", special_register); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -97,6 +97,8 @@ struct Profile { | |||||||
|     std::optional<CompareFunction> alpha_test_func; |     std::optional<CompareFunction> alpha_test_func; | ||||||
|     float alpha_test_reference{}; |     float alpha_test_reference{}; | ||||||
|  |  | ||||||
|  |     bool y_negate{}; | ||||||
|  |  | ||||||
|     std::vector<TransformFeedbackVarying> xfb_varyings; |     std::vector<TransformFeedbackVarying> xfb_varyings; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -82,6 +82,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, | |||||||
|     alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref); |     alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref); | ||||||
|     point_size = Common::BitCast<u32>(regs.point_size); |     point_size = Common::BitCast<u32>(regs.point_size); | ||||||
|  |  | ||||||
|  |     y_negate.Assign(regs.screen_y_control.y_negate != 0 ? 1 : 0); | ||||||
|  |  | ||||||
|     if (maxwell3d.dirty.flags[Dirty::InstanceDivisors]) { |     if (maxwell3d.dirty.flags[Dirty::InstanceDivisors]) { | ||||||
|         maxwell3d.dirty.flags[Dirty::InstanceDivisors] = false; |         maxwell3d.dirty.flags[Dirty::InstanceDivisors] = false; | ||||||
|         for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { |         for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | ||||||
|   | |||||||
| @@ -202,6 +202,7 @@ struct FixedPipelineState { | |||||||
|         BitField<3, 1, u32> early_z; |         BitField<3, 1, u32> early_z; | ||||||
|         BitField<4, 1, u32> depth_enabled; |         BitField<4, 1, u32> depth_enabled; | ||||||
|         BitField<5, 5, u32> depth_format; |         BitField<5, 5, u32> depth_format; | ||||||
|  |         BitField<10, 1, u32> y_negate; | ||||||
|     }; |     }; | ||||||
|     std::array<u8, Maxwell::NumRenderTargets> color_formats; |     std::array<u8, Maxwell::NumRenderTargets> color_formats; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1116,6 +1116,7 @@ Shader::Profile PipelineCache::MakeProfile(const GraphicsPipelineCacheKey& key, | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     profile.force_early_z = key.state.early_z != 0; |     profile.force_early_z = key.state.early_z != 0; | ||||||
|  |     profile.y_negate = key.state.y_negate != 0; | ||||||
|     return profile; |     return profile; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user