diff options
Diffstat (limited to 'src/shader_recompiler/backend')
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 29 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | 29 |
2 files changed, 46 insertions, 12 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 4d5dabcbf..a8ca33c1d 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -76,6 +76,8 @@ Id GetAttributeType(EmitContext& ctx, AttributeType type) { | |||
| 76 | return ctx.TypeVector(ctx.TypeInt(32, true), 4); | 76 | return ctx.TypeVector(ctx.TypeInt(32, true), 4); |
| 77 | case AttributeType::UnsignedInt: | 77 | case AttributeType::UnsignedInt: |
| 78 | return ctx.U32[4]; | 78 | return ctx.U32[4]; |
| 79 | case AttributeType::Disabled: | ||
| 80 | break; | ||
| 79 | } | 81 | } |
| 80 | throw InvalidArgument("Invalid attribute type {}", type); | 82 | throw InvalidArgument("Invalid attribute type {}", type); |
| 81 | } | 83 | } |
| @@ -305,15 +307,36 @@ void EmitContext::DefineInputs(const Info& info) { | |||
| 305 | if (info.loads_front_face) { | 307 | if (info.loads_front_face) { |
| 306 | front_face = DefineInput(*this, U1, spv::BuiltIn::FrontFacing); | 308 | front_face = DefineInput(*this, U1, spv::BuiltIn::FrontFacing); |
| 307 | } | 309 | } |
| 308 | for (size_t index = 0; index < info.loads_generics.size(); ++index) { | 310 | for (size_t index = 0; index < info.input_generics.size(); ++index) { |
| 309 | if (!info.loads_generics[index]) { | 311 | const InputVarying generic{info.input_generics[index]}; |
| 312 | if (!generic.used) { | ||
| 310 | continue; | 313 | continue; |
| 311 | } | 314 | } |
| 312 | const Id type{GetAttributeType(*this, profile.generic_input_types[index])}; | 315 | const AttributeType input_type{profile.generic_input_types[index]}; |
| 316 | if (input_type == AttributeType::Disabled) { | ||
| 317 | continue; | ||
| 318 | } | ||
| 319 | const Id type{GetAttributeType(*this, input_type)}; | ||
| 313 | const Id id{DefineInput(*this, type)}; | 320 | const Id id{DefineInput(*this, type)}; |
| 314 | Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); | 321 | Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); |
| 315 | Name(id, fmt::format("in_attr{}", index)); | 322 | Name(id, fmt::format("in_attr{}", index)); |
| 316 | input_generics[index] = id; | 323 | input_generics[index] = id; |
| 324 | |||
| 325 | if (stage != Stage::Fragment) { | ||
| 326 | continue; | ||
| 327 | } | ||
| 328 | switch (generic.interpolation) { | ||
| 329 | case Interpolation::Smooth: | ||
| 330 | // Default | ||
| 331 | // Decorate(id, spv::Decoration::Smooth); | ||
| 332 | break; | ||
| 333 | case Interpolation::NoPerspective: | ||
| 334 | Decorate(id, spv::Decoration::NoPerspective); | ||
| 335 | break; | ||
| 336 | case Interpolation::Flat: | ||
| 337 | Decorate(id, spv::Decoration::Flat); | ||
| 338 | break; | ||
| 339 | } | ||
| 317 | } | 340 | } |
| 318 | } | 341 | } |
| 319 | 342 | ||
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 6fa16eb80..4cbc2aec1 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 | |||
| @@ -10,16 +10,23 @@ | |||
| 10 | 10 | ||
| 11 | namespace Shader::Backend::SPIRV { | 11 | namespace Shader::Backend::SPIRV { |
| 12 | namespace { | 12 | namespace { |
| 13 | std::tuple<Id, Id, bool> AttrTypes(EmitContext& ctx, u32 index) { | 13 | struct AttrInfo { |
| 14 | const bool is_first_reader{ctx.stage == Stage::VertexB}; | 14 | Id pointer; |
| 15 | Id id; | ||
| 16 | bool needs_cast; | ||
| 17 | }; | ||
| 18 | |||
| 19 | std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { | ||
| 15 | const AttributeType type{ctx.profile.generic_input_types.at(index)}; | 20 | const AttributeType type{ctx.profile.generic_input_types.at(index)}; |
| 16 | switch (type) { | 21 | switch (type) { |
| 17 | case AttributeType::Float: | 22 | case AttributeType::Float: |
| 18 | return {ctx.input_f32, ctx.F32[1], false}; | 23 | return AttrInfo{ctx.input_f32, ctx.F32[1], false}; |
| 19 | case AttributeType::UnsignedInt: | 24 | case AttributeType::UnsignedInt: |
| 20 | return {ctx.input_u32, ctx.U32[1], true}; | 25 | return AttrInfo{ctx.input_u32, ctx.U32[1], true}; |
| 21 | case AttributeType::SignedInt: | 26 | case AttributeType::SignedInt: |
| 22 | return {ctx.input_s32, ctx.TypeInt(32, true), true}; | 27 | return AttrInfo{ctx.input_s32, ctx.TypeInt(32, true), true}; |
| 28 | case AttributeType::Disabled: | ||
| 29 | return std::nullopt; | ||
| 23 | } | 30 | } |
| 24 | throw InvalidArgument("Invalid attribute type {}", type); | 31 | throw InvalidArgument("Invalid attribute type {}", type); |
| 25 | } | 32 | } |
| @@ -129,11 +136,15 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr) { | |||
| 129 | const auto element_id{[&] { return ctx.Constant(ctx.U32[1], element); }}; | 136 | const auto element_id{[&] { return ctx.Constant(ctx.U32[1], element); }}; |
| 130 | if (IR::IsGeneric(attr)) { | 137 | if (IR::IsGeneric(attr)) { |
| 131 | const u32 index{IR::GenericAttributeIndex(attr)}; | 138 | const u32 index{IR::GenericAttributeIndex(attr)}; |
| 132 | const auto [pointer_type, type, needs_cast]{AttrTypes(ctx, index)}; | 139 | const std::optional<AttrInfo> type{AttrTypes(ctx, index)}; |
| 140 | if (!type) { | ||
| 141 | // Attribute is disabled | ||
| 142 | return ctx.Constant(ctx.F32[1], 0.0f); | ||
| 143 | } | ||
| 133 | const Id generic_id{ctx.input_generics.at(index)}; | 144 | const Id generic_id{ctx.input_generics.at(index)}; |
| 134 | const Id pointer{ctx.OpAccessChain(pointer_type, generic_id, element_id())}; | 145 | const Id pointer{ctx.OpAccessChain(type->pointer, generic_id, element_id())}; |
| 135 | const Id value{ctx.OpLoad(type, pointer)}; | 146 | const Id value{ctx.OpLoad(type->id, pointer)}; |
| 136 | return needs_cast ? ctx.OpBitcast(ctx.F32[1], value) : value; | 147 | return type->needs_cast ? ctx.OpBitcast(ctx.F32[1], value) : value; |
| 137 | } | 148 | } |
| 138 | switch (attr) { | 149 | switch (attr) { |
| 139 | case IR::Attribute::PositionX: | 150 | case IR::Attribute::PositionX: |