diff options
Diffstat (limited to 'src/shader_recompiler/backend/spirv/spirv_emit_context.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index ecb2db494..eb1e3e0b6 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | |||
| @@ -721,9 +721,21 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) { | |||
| 721 | size_t label_index{0}; | 721 | size_t label_index{0}; |
| 722 | if (info.loads.AnyComponent(IR::Attribute::PositionX)) { | 722 | if (info.loads.AnyComponent(IR::Attribute::PositionX)) { |
| 723 | AddLabel(labels[label_index]); | 723 | AddLabel(labels[label_index]); |
| 724 | const Id pointer{is_array | 724 | const Id pointer{[&]() { |
| 725 | ? OpAccessChain(input_f32, input_position, vertex, masked_index) | 725 | if (need_input_position_indirect) { |
| 726 | : OpAccessChain(input_f32, input_position, masked_index)}; | 726 | if (is_array) |
| 727 | return OpAccessChain(input_f32, input_position, vertex, u32_zero_value, | ||
| 728 | masked_index); | ||
| 729 | else | ||
| 730 | return OpAccessChain(input_f32, input_position, u32_zero_value, | ||
| 731 | masked_index); | ||
| 732 | } else { | ||
| 733 | if (is_array) | ||
| 734 | return OpAccessChain(input_f32, input_position, vertex, masked_index); | ||
| 735 | else | ||
| 736 | return OpAccessChain(input_f32, input_position, masked_index); | ||
| 737 | } | ||
| 738 | }()}; | ||
| 727 | const Id result{OpLoad(F32[1], pointer)}; | 739 | const Id result{OpLoad(F32[1], pointer)}; |
| 728 | OpReturnValue(result); | 740 | OpReturnValue(result); |
| 729 | ++label_index; | 741 | ++label_index; |
| @@ -1367,12 +1379,24 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1367 | Decorate(layer, spv::Decoration::Flat); | 1379 | Decorate(layer, spv::Decoration::Flat); |
| 1368 | } | 1380 | } |
| 1369 | if (loads.AnyComponent(IR::Attribute::PositionX)) { | 1381 | if (loads.AnyComponent(IR::Attribute::PositionX)) { |
| 1370 | const bool is_fragment{stage != Stage::Fragment}; | 1382 | const bool is_fragment{stage == Stage::Fragment}; |
| 1371 | const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::Position : spv::BuiltIn::FragCoord}; | 1383 | if (!is_fragment && profile.has_broken_spirv_position_input) { |
| 1372 | input_position = DefineInput(*this, F32[4], true, built_in); | 1384 | need_input_position_indirect = true; |
| 1373 | if (profile.support_geometry_shader_passthrough) { | 1385 | |
| 1374 | if (info.passthrough.AnyComponent(IR::Attribute::PositionX)) { | 1386 | const Id input_position_struct = TypeStruct(F32[4]); |
| 1375 | Decorate(input_position, spv::Decoration::PassthroughNV); | 1387 | input_position = DefineInput(*this, input_position_struct, true); |
| 1388 | |||
| 1389 | MemberDecorate(input_position_struct, 0, spv::Decoration::BuiltIn, | ||
| 1390 | static_cast<unsigned>(spv::BuiltIn::Position)); | ||
| 1391 | Decorate(input_position_struct, spv::Decoration::Block); | ||
| 1392 | } else { | ||
| 1393 | const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::FragCoord : spv::BuiltIn::Position}; | ||
| 1394 | input_position = DefineInput(*this, F32[4], true, built_in); | ||
| 1395 | |||
| 1396 | if (profile.support_geometry_shader_passthrough) { | ||
| 1397 | if (info.passthrough.AnyComponent(IR::Attribute::PositionX)) { | ||
| 1398 | Decorate(input_position, spv::Decoration::PassthroughNV); | ||
| 1399 | } | ||
| 1376 | } | 1400 | } |
| 1377 | } | 1401 | } |
| 1378 | } | 1402 | } |