summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/spirv/spirv_emit_context.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp61
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
28struct AttrInfo {
29 Id pointer;
30 Id id;
31 bool needs_cast;
32};
33
34Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { 28Id 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
215std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) { 214InputGenericInfo 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);