summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h1
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp7
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h1
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc1
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp2
-rw-r--r--src/shader_recompiler/profile.h2
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp2
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp1
10 files changed, 22 insertions, 0 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index d43c72f6e..7949d08d0 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -72,6 +72,7 @@ Id EmitLocalInvocationId(EmitContext& ctx);
72Id EmitInvocationId(EmitContext& ctx); 72Id EmitInvocationId(EmitContext& ctx);
73Id EmitSampleId(EmitContext& ctx); 73Id EmitSampleId(EmitContext& ctx);
74Id EmitIsHelperInvocation(EmitContext& ctx); 74Id EmitIsHelperInvocation(EmitContext& ctx);
75Id EmitYDirection(EmitContext& ctx);
75Id EmitLoadLocal(EmitContext& ctx, Id word_offset); 76Id EmitLoadLocal(EmitContext& ctx, Id word_offset);
76void EmitWriteLocal(EmitContext& ctx, Id word_offset, Id value); 77void EmitWriteLocal(EmitContext& ctx, Id word_offset, Id value);
77Id EmitUndefU1(EmitContext& ctx); 78Id EmitUndefU1(EmitContext& ctx);
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index e5e4c352b..1030404c0 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -403,6 +403,13 @@ Id EmitIsHelperInvocation(EmitContext& ctx) {
403 return ctx.OpLoad(ctx.U1, ctx.is_helper_invocation); 403 return ctx.OpLoad(ctx.U1, ctx.is_helper_invocation);
404} 404}
405 405
406Id EmitYDirection(EmitContext& ctx) {
407 if (ctx.profile.y_negate) {
408 return ctx.Constant(ctx.F32[1], -1.0f);
409 }
410 return ctx.Constant(ctx.F32[1], 1.0f);
411}
412
406Id EmitLoadLocal(EmitContext& ctx, Id word_offset) { 413Id EmitLoadLocal(EmitContext& ctx, Id word_offset) {
407 const Id pointer{ctx.OpAccessChain(ctx.private_u32, ctx.local_memory, word_offset)}; 414 const Id pointer{ctx.OpAccessChain(ctx.private_u32, ctx.local_memory, word_offset)};
408 return ctx.OpLoad(ctx.U32[1], pointer); 415 return ctx.OpLoad(ctx.U32[1], pointer);
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index aebe7200f..c3e8d0681 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -379,6 +379,10 @@ U1 IREmitter::IsHelperInvocation() {
379 return Inst<U1>(Opcode::IsHelperInvocation); 379 return Inst<U1>(Opcode::IsHelperInvocation);
380} 380}
381 381
382F32 IREmitter::YDirection() {
383 return Inst<F32>(Opcode::YDirection);
384}
385
382U32 IREmitter::LaneId() { 386U32 IREmitter::LaneId() {
383 return Inst<U32>(Opcode::LaneId); 387 return Inst<U32>(Opcode::LaneId);
384} 388}
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index b9d051b43..7e67f5e30 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -102,6 +102,7 @@ public:
102 [[nodiscard]] U32 InvocationId(); 102 [[nodiscard]] U32 InvocationId();
103 [[nodiscard]] U32 SampleId(); 103 [[nodiscard]] U32 SampleId();
104 [[nodiscard]] U1 IsHelperInvocation(); 104 [[nodiscard]] U1 IsHelperInvocation();
105 [[nodiscard]] F32 YDirection();
105 106
106 [[nodiscard]] U32 LaneId(); 107 [[nodiscard]] U32 LaneId();
107 108
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 1cfc2a943..269de8ca5 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -65,6 +65,7 @@ OPCODE(LocalInvocationId, U32x3,
65OPCODE(InvocationId, U32, ) 65OPCODE(InvocationId, U32, )
66OPCODE(SampleId, U32, ) 66OPCODE(SampleId, U32, )
67OPCODE(IsHelperInvocation, U1, ) 67OPCODE(IsHelperInvocation, U1, )
68OPCODE(YDirection, F32, )
68 69
69// Undefined 70// Undefined
70OPCODE(UndefU1, U1, ) 71OPCODE(UndefU1, U1, )
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp
index 660b84c20..b0baff74b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp
@@ -150,6 +150,8 @@ enum class SpecialRegister : u64 {
150 return ir.SubgroupGtMask(); 150 return ir.SubgroupGtMask();
151 case SpecialRegister::SR_GEMASK: 151 case SpecialRegister::SR_GEMASK:
152 return ir.SubgroupGeMask(); 152 return ir.SubgroupGeMask();
153 case SpecialRegister::SR_Y_DIRECTION:
154 return ir.BitCast<IR::U32>(ir.YDirection());
153 default: 155 default:
154 throw NotImplementedException("S2R special register {}", special_register); 156 throw NotImplementedException("S2R special register {}", special_register);
155 } 157 }
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h
index a2c2948d5..08242184f 100644
--- a/src/shader_recompiler/profile.h
+++ b/src/shader_recompiler/profile.h
@@ -97,6 +97,8 @@ struct Profile {
97 std::optional<CompareFunction> alpha_test_func; 97 std::optional<CompareFunction> alpha_test_func;
98 float alpha_test_reference{}; 98 float alpha_test_reference{};
99 99
100 bool y_negate{};
101
100 std::vector<TransformFeedbackVarying> xfb_varyings; 102 std::vector<TransformFeedbackVarying> xfb_varyings;
101}; 103};
102 104
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 6a3baf837..24834e0f7 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -82,6 +82,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
82 alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref); 82 alpha_test_ref = Common::BitCast<u32>(regs.alpha_test_ref);
83 point_size = Common::BitCast<u32>(regs.point_size); 83 point_size = Common::BitCast<u32>(regs.point_size);
84 84
85 y_negate.Assign(regs.screen_y_control.y_negate != 0 ? 1 : 0);
86
85 if (maxwell3d.dirty.flags[Dirty::InstanceDivisors]) { 87 if (maxwell3d.dirty.flags[Dirty::InstanceDivisors]) {
86 maxwell3d.dirty.flags[Dirty::InstanceDivisors] = false; 88 maxwell3d.dirty.flags[Dirty::InstanceDivisors] = false;
87 for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { 89 for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 5568c4f72..31de6b2c8 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -202,6 +202,7 @@ struct FixedPipelineState {
202 BitField<3, 1, u32> early_z; 202 BitField<3, 1, u32> early_z;
203 BitField<4, 1, u32> depth_enabled; 203 BitField<4, 1, u32> depth_enabled;
204 BitField<5, 5, u32> depth_format; 204 BitField<5, 5, u32> depth_format;
205 BitField<10, 1, u32> y_negate;
205 }; 206 };
206 std::array<u8, Maxwell::NumRenderTargets> color_formats; 207 std::array<u8, Maxwell::NumRenderTargets> color_formats;
207 208
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 4d0d3ebb7..e9b93336b 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -1116,6 +1116,7 @@ Shader::Profile PipelineCache::MakeProfile(const GraphicsPipelineCacheKey& key,
1116 break; 1116 break;
1117 } 1117 }
1118 profile.force_early_z = key.state.early_z != 0; 1118 profile.force_early_z = key.state.early_z != 0;
1119 profile.y_negate = key.state.y_negate != 0;
1119 return profile; 1120 return profile;
1120} 1121}
1121 1122