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 | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 47739794f..fd15f47ea 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | |||
| @@ -25,12 +25,6 @@ enum class Operation { | |||
| 25 | FPMax, | 25 | FPMax, |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | struct AttrInfo { | ||
| 29 | Id pointer; | ||
| 30 | Id id; | ||
| 31 | bool needs_cast; | ||
| 32 | }; | ||
| 33 | |||
| 34 | Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { | 28 | Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { |
| 35 | const spv::ImageFormat format{spv::ImageFormat::Unknown}; | 29 | const spv::ImageFormat format{spv::ImageFormat::Unknown}; |
| 36 | const Id type{ctx.F32[1]}; | 30 | const Id type{ctx.F32[1]}; |
| @@ -206,23 +200,37 @@ Id GetAttributeType(EmitContext& ctx, AttributeType type) { | |||
| 206 | return ctx.TypeVector(ctx.TypeInt(32, true), 4); | 200 | return ctx.TypeVector(ctx.TypeInt(32, true), 4); |
| 207 | case AttributeType::UnsignedInt: | 201 | case AttributeType::UnsignedInt: |
| 208 | return ctx.U32[4]; | 202 | return ctx.U32[4]; |
| 203 | case AttributeType::SignedScaled: | ||
| 204 | return ctx.profile.support_scaled_attributes ? ctx.F32[4] | ||
| 205 | : ctx.TypeVector(ctx.TypeInt(32, true), 4); | ||
| 206 | case AttributeType::UnsignedScaled: | ||
| 207 | return ctx.profile.support_scaled_attributes ? ctx.F32[4] : ctx.U32[4]; | ||
| 209 | case AttributeType::Disabled: | 208 | case AttributeType::Disabled: |
| 210 | break; | 209 | break; |
| 211 | } | 210 | } |
| 212 | throw InvalidArgument("Invalid attribute type {}", type); | 211 | throw InvalidArgument("Invalid attribute type {}", type); |
| 213 | } | 212 | } |
| 214 | 213 | ||
| 215 | std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { | 214 | InputGenericInfo GetAttributeInfo(EmitContext& ctx, AttributeType type, Id id) { |
| 216 | const AttributeType type{ctx.runtime_info.generic_input_types.at(index)}; | ||
| 217 | switch (type) { | 215 | switch (type) { |
| 218 | case AttributeType::Float: | 216 | case AttributeType::Float: |
| 219 | return AttrInfo{ctx.input_f32, ctx.F32[1], false}; | 217 | return InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None}; |
| 220 | case AttributeType::UnsignedInt: | 218 | case AttributeType::UnsignedInt: |
| 221 | return AttrInfo{ctx.input_u32, ctx.U32[1], true}; | 219 | return InputGenericInfo{id, ctx.input_u32, ctx.U32[1], InputGenericLoadOp::Bitcast}; |
| 222 | case AttributeType::SignedInt: | 220 | case AttributeType::SignedInt: |
| 223 | return AttrInfo{ctx.input_s32, ctx.TypeInt(32, true), true}; | 221 | return InputGenericInfo{id, ctx.input_s32, ctx.TypeInt(32, true), |
| 222 | InputGenericLoadOp::Bitcast}; | ||
| 223 | case AttributeType::SignedScaled: | ||
| 224 | return ctx.profile.support_scaled_attributes | ||
| 225 | ? InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None} | ||
| 226 | : InputGenericInfo{id, ctx.input_s32, ctx.TypeInt(32, true), | ||
| 227 | InputGenericLoadOp::SToF}; | ||
| 228 | case AttributeType::UnsignedScaled: | ||
| 229 | return ctx.profile.support_scaled_attributes | ||
| 230 | ? InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None} | ||
| 231 | : InputGenericInfo{id, ctx.input_u32, ctx.U32[1], InputGenericLoadOp::UToF}; | ||
| 224 | case AttributeType::Disabled: | 232 | case AttributeType::Disabled: |
| 225 | return std::nullopt; | 233 | return InputGenericInfo{}; |
| 226 | } | 234 | } |
| 227 | throw InvalidArgument("Invalid attribute type {}", type); | 235 | throw InvalidArgument("Invalid attribute type {}", type); |
| 228 | } | 236 | } |
| @@ -746,18 +754,29 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) { | |||
| 746 | continue; | 754 | continue; |
| 747 | } | 755 | } |
| 748 | AddLabel(labels[label_index]); | 756 | AddLabel(labels[label_index]); |
| 749 | const auto type{AttrTypes(*this, static_cast<u32>(index))}; | 757 | const auto& generic{input_generics.at(index)}; |
| 750 | if (!type) { | 758 | const Id generic_id{generic.id}; |
| 759 | if (!ValidId(generic_id)) { | ||
| 751 | OpReturnValue(Const(0.0f)); | 760 | OpReturnValue(Const(0.0f)); |
| 752 | ++label_index; | 761 | ++label_index; |
| 753 | continue; | 762 | continue; |
| 754 | } | 763 | } |
| 755 | const Id generic_id{input_generics.at(index)}; | 764 | const Id pointer{ |
| 756 | const Id pointer{is_array | 765 | is_array ? OpAccessChain(generic.pointer_type, generic_id, vertex, masked_index) |
| 757 | ? OpAccessChain(type->pointer, generic_id, vertex, masked_index) | 766 | : OpAccessChain(generic.pointer_type, generic_id, masked_index)}; |
| 758 | : OpAccessChain(type->pointer, generic_id, masked_index)}; | 767 | const Id value{OpLoad(generic.component_type, pointer)}; |
| 759 | const Id value{OpLoad(type->id, pointer)}; | 768 | const Id result{[this, generic, value]() { |
| 760 | const Id result{type->needs_cast ? OpBitcast(F32[1], value) : value}; | 769 | switch (generic.load_op) { |
| 770 | case InputGenericLoadOp::Bitcast: | ||
| 771 | return OpBitcast(F32[1], value); | ||
| 772 | case InputGenericLoadOp::SToF: | ||
| 773 | return OpConvertSToF(F32[1], value); | ||
| 774 | case InputGenericLoadOp::UToF: | ||
| 775 | return OpConvertUToF(F32[1], value); | ||
| 776 | default: | ||
| 777 | return value; | ||
| 778 | }; | ||
| 779 | }()}; | ||
| 761 | OpReturnValue(result); | 780 | OpReturnValue(result); |
| 762 | ++label_index; | 781 | ++label_index; |
| 763 | } | 782 | } |
| @@ -1457,7 +1476,7 @@ void EmitContext::DefineInputs(const IR::Program& program) { | |||
| 1457 | const Id id{DefineInput(*this, type, true)}; | 1476 | const Id id{DefineInput(*this, type, true)}; |
| 1458 | Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); | 1477 | Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); |
| 1459 | Name(id, fmt::format("in_attr{}", index)); | 1478 | Name(id, fmt::format("in_attr{}", index)); |
| 1460 | input_generics[index] = id; | 1479 | input_generics[index] = GetAttributeInfo(*this, input_type, id); |
| 1461 | 1480 | ||
| 1462 | if (info.passthrough.Generic(index) && profile.support_geometry_shader_passthrough) { | 1481 | if (info.passthrough.Generic(index) && profile.support_geometry_shader_passthrough) { |
| 1463 | Decorate(id, spv::Decoration::PassthroughNV); | 1482 | Decorate(id, spv::Decoration::PassthroughNV); |