diff options
Diffstat (limited to '')
-rw-r--r-- | src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index a0c155fdb..bec5db173 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -25,16 +25,11 @@ enum class Operation { FPMax, }; -struct AttrInfo { - Id pointer; - Id id; - bool needs_cast; -}; - Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { const spv::ImageFormat format{spv::ImageFormat::Unknown}; const Id type{ctx.F32[1]}; const bool depth{desc.is_depth}; + const bool ms{desc.is_multisample}; switch (desc.type) { case TextureType::Color1D: return ctx.TypeImage(type, spv::Dim::Dim1D, depth, false, false, 1, format); @@ -42,9 +37,9 @@ Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { return ctx.TypeImage(type, spv::Dim::Dim1D, depth, true, false, 1, format); case TextureType::Color2D: case TextureType::Color2DRect: - return ctx.TypeImage(type, spv::Dim::Dim2D, depth, false, false, 1, format); + return ctx.TypeImage(type, spv::Dim::Dim2D, depth, false, ms, 1, format); case TextureType::ColorArray2D: - return ctx.TypeImage(type, spv::Dim::Dim2D, depth, true, false, 1, format); + return ctx.TypeImage(type, spv::Dim::Dim2D, depth, true, ms, 1, format); case TextureType::Color3D: return ctx.TypeImage(type, spv::Dim::Dim3D, depth, false, false, 1, format); case TextureType::ColorCube: @@ -165,7 +160,7 @@ void DefineGenericOutput(EmitContext& ctx, size_t index, std::optional<u32> invo const u32 remainder{4 - element}; const TransformFeedbackVarying* xfb_varying{}; const size_t xfb_varying_index{base_attr_index + element}; - if (xfb_varying_index < ctx.runtime_info.xfb_varyings.size()) { + if (xfb_varying_index < ctx.runtime_info.xfb_count) { xfb_varying = &ctx.runtime_info.xfb_varyings[xfb_varying_index]; xfb_varying = xfb_varying->components > 0 ? xfb_varying : nullptr; } @@ -205,23 +200,37 @@ Id GetAttributeType(EmitContext& ctx, AttributeType type) { return ctx.TypeVector(ctx.TypeInt(32, true), 4); case AttributeType::UnsignedInt: return ctx.U32[4]; + case AttributeType::SignedScaled: + return ctx.profile.support_scaled_attributes ? ctx.F32[4] + : ctx.TypeVector(ctx.TypeInt(32, true), 4); + case AttributeType::UnsignedScaled: + return ctx.profile.support_scaled_attributes ? ctx.F32[4] : ctx.U32[4]; case AttributeType::Disabled: break; } throw InvalidArgument("Invalid attribute type {}", type); } -std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { - const AttributeType type{ctx.runtime_info.generic_input_types.at(index)}; +InputGenericInfo GetAttributeInfo(EmitContext& ctx, AttributeType type, Id id) { switch (type) { case AttributeType::Float: - return AttrInfo{ctx.input_f32, ctx.F32[1], false}; + return InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None}; case AttributeType::UnsignedInt: - return AttrInfo{ctx.input_u32, ctx.U32[1], true}; + return InputGenericInfo{id, ctx.input_u32, ctx.U32[1], InputGenericLoadOp::Bitcast}; case AttributeType::SignedInt: - return AttrInfo{ctx.input_s32, ctx.TypeInt(32, true), true}; + return InputGenericInfo{id, ctx.input_s32, ctx.TypeInt(32, true), + InputGenericLoadOp::Bitcast}; + case AttributeType::SignedScaled: + return ctx.profile.support_scaled_attributes + ? InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None} + : InputGenericInfo{id, ctx.input_s32, ctx.TypeInt(32, true), + InputGenericLoadOp::SToF}; + case AttributeType::UnsignedScaled: + return ctx.profile.support_scaled_attributes + ? InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None} + : InputGenericInfo{id, ctx.input_u32, ctx.U32[1], InputGenericLoadOp::UToF}; case AttributeType::Disabled: - return std::nullopt; + return InputGenericInfo{}; } throw InvalidArgument("Invalid attribute type {}", type); } @@ -745,18 +754,29 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) { continue; } AddLabel(labels[label_index]); - const auto type{AttrTypes(*this, static_cast<u32>(index))}; - if (!type) { + const auto& generic{input_generics.at(index)}; + const Id generic_id{generic.id}; + if (!ValidId(generic_id)) { OpReturnValue(Const(0.0f)); ++label_index; continue; } - const Id generic_id{input_generics.at(index)}; - const Id pointer{is_array - ? OpAccessChain(type->pointer, generic_id, vertex, masked_index) - : OpAccessChain(type->pointer, generic_id, masked_index)}; - const Id value{OpLoad(type->id, pointer)}; - const Id result{type->needs_cast ? OpBitcast(F32[1], value) : value}; + const Id pointer{ + is_array ? OpAccessChain(generic.pointer_type, generic_id, vertex, masked_index) + : OpAccessChain(generic.pointer_type, generic_id, masked_index)}; + const Id value{OpLoad(generic.component_type, pointer)}; + const Id result{[this, generic, value]() { + switch (generic.load_op) { + case InputGenericLoadOp::Bitcast: + return OpBitcast(F32[1], value); + case InputGenericLoadOp::SToF: + return OpConvertSToF(F32[1], value); + case InputGenericLoadOp::UToF: + return OpConvertUToF(F32[1], value); + default: + return value; + }; + }()}; OpReturnValue(result); ++label_index; } @@ -1287,6 +1307,7 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in .pointer_type = pointer_type, .image_type = image_type, .count = desc.count, + .is_multisample = desc.is_multisample, }); if (profile.supported_spirv >= 0x00010400) { interfaces.push_back(id); @@ -1455,7 +1476,7 @@ void EmitContext::DefineInputs(const IR::Program& program) { const Id id{DefineInput(*this, type, true)}; Decorate(id, spv::Decoration::Location, static_cast<u32>(index)); Name(id, fmt::format("in_attr{}", index)); - input_generics[index] = id; + input_generics[index] = GetAttributeInfo(*this, input_type, id); if (info.passthrough.Generic(index) && profile.support_geometry_shader_passthrough) { Decorate(id, spv::Decoration::PassthroughNV); @@ -1570,7 +1591,8 @@ void EmitContext::DefineOutputs(const IR::Program& program) { Decorate(frag_depth, spv::Decoration::BuiltIn, spv::BuiltIn::FragDepth); } if (info.stores_sample_mask) { - sample_mask = DefineOutput(*this, U32[1], std::nullopt); + const Id array_type{TypeArray(U32[1], Const(1U))}; + sample_mask = DefineOutput(*this, array_type, std::nullopt); Decorate(sample_mask, spv::Decoration::BuiltIn, spv::BuiltIn::SampleMask); } break; |