|
@@ -721,9 +721,21 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) {
|
|
|
size_t label_index{0};
|
|
size_t label_index{0};
|
|
|
if (info.loads.AnyComponent(IR::Attribute::PositionX)) {
|
|
if (info.loads.AnyComponent(IR::Attribute::PositionX)) {
|
|
|
AddLabel(labels[label_index]);
|
|
AddLabel(labels[label_index]);
|
|
|
- const Id pointer{is_array
|
|
|
|
|
- ? OpAccessChain(input_f32, input_position, vertex, masked_index)
|
|
|
|
|
- : OpAccessChain(input_f32, input_position, masked_index)};
|
|
|
|
|
|
|
+ const Id pointer{[&]() {
|
|
|
|
|
+ if (need_input_position_indirect) {
|
|
|
|
|
+ if (is_array)
|
|
|
|
|
+ return OpAccessChain(input_f32, input_position, vertex, u32_zero_value,
|
|
|
|
|
+ masked_index);
|
|
|
|
|
+ else
|
|
|
|
|
+ return OpAccessChain(input_f32, input_position, u32_zero_value,
|
|
|
|
|
+ masked_index);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (is_array)
|
|
|
|
|
+ return OpAccessChain(input_f32, input_position, vertex, masked_index);
|
|
|
|
|
+ else
|
|
|
|
|
+ return OpAccessChain(input_f32, input_position, masked_index);
|
|
|
|
|
+ }
|
|
|
|
|
+ }()};
|
|
|
const Id result{OpLoad(F32[1], pointer)};
|
|
const Id result{OpLoad(F32[1], pointer)};
|
|
|
OpReturnValue(result);
|
|
OpReturnValue(result);
|
|
|
++label_index;
|
|
++label_index;
|
|
@@ -1367,12 +1379,24 @@ void EmitContext::DefineInputs(const IR::Program& program) {
|
|
|
Decorate(layer, spv::Decoration::Flat);
|
|
Decorate(layer, spv::Decoration::Flat);
|
|
|
}
|
|
}
|
|
|
if (loads.AnyComponent(IR::Attribute::PositionX)) {
|
|
if (loads.AnyComponent(IR::Attribute::PositionX)) {
|
|
|
- const bool is_fragment{stage != Stage::Fragment};
|
|
|
|
|
- const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::Position : spv::BuiltIn::FragCoord};
|
|
|
|
|
- input_position = DefineInput(*this, F32[4], true, built_in);
|
|
|
|
|
- if (profile.support_geometry_shader_passthrough) {
|
|
|
|
|
- if (info.passthrough.AnyComponent(IR::Attribute::PositionX)) {
|
|
|
|
|
- Decorate(input_position, spv::Decoration::PassthroughNV);
|
|
|
|
|
|
|
+ const bool is_fragment{stage == Stage::Fragment};
|
|
|
|
|
+ if (!is_fragment && profile.has_broken_spirv_position_input) {
|
|
|
|
|
+ need_input_position_indirect = true;
|
|
|
|
|
+
|
|
|
|
|
+ const Id input_position_struct = TypeStruct(F32[4]);
|
|
|
|
|
+ input_position = DefineInput(*this, input_position_struct, true);
|
|
|
|
|
+
|
|
|
|
|
+ MemberDecorate(input_position_struct, 0, spv::Decoration::BuiltIn,
|
|
|
|
|
+ static_cast<unsigned>(spv::BuiltIn::Position));
|
|
|
|
|
+ Decorate(input_position_struct, spv::Decoration::Block);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const spv::BuiltIn built_in{is_fragment ? spv::BuiltIn::FragCoord : spv::BuiltIn::Position};
|
|
|
|
|
+ input_position = DefineInput(*this, F32[4], true, built_in);
|
|
|
|
|
+
|
|
|
|
|
+ if (profile.support_geometry_shader_passthrough) {
|
|
|
|
|
+ if (info.passthrough.AnyComponent(IR::Attribute::PositionX)) {
|
|
|
|
|
+ Decorate(input_position, spv::Decoration::PassthroughNV);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|