diff options
| author | 2021-03-26 16:46:07 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:24 -0400 | |
| commit | d9c5bd9509e82fcde72c18663989931f97ed6518 (patch) | |
| tree | d6575e66d66a8abc8ee8776c1c2536c052424787 /src/shader_recompiler | |
| parent | shader: Add IR opcode for ImageFetch (diff) | |
| download | yuzu-d9c5bd9509e82fcde72c18663989931f97ed6518.tar.gz yuzu-d9c5bd9509e82fcde72c18663989931f97ed6518.tar.xz yuzu-d9c5bd9509e82fcde72c18663989931f97ed6518.zip | |
shader: Refactor PTP and other minor changes
Diffstat (limited to '')
14 files changed, 67 insertions, 123 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 7d8b938d1..50793b5bf 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -169,7 +169,6 @@ void EmitContext::DefineCommonTypes(const Info& info) { | |||
| 169 | AddCapability(spv::Capability::Float64); | 169 | AddCapability(spv::Capability::Float64); |
| 170 | F64.Define(*this, TypeFloat(64), "f64"); | 170 | F64.Define(*this, TypeFloat(64), "f64"); |
| 171 | } | 171 | } |
| 172 | array_U32x2 = Name(TypeArray(U32[2], Constant(U32[1], 4U)), "array-u32x2"); | ||
| 173 | } | 172 | } |
| 174 | 173 | ||
| 175 | void EmitContext::DefineCommonConstants() { | 174 | void EmitContext::DefineCommonConstants() { |
| @@ -352,20 +351,19 @@ void EmitContext::DefineOutputs(const Info& info) { | |||
| 352 | } | 351 | } |
| 353 | } | 352 | } |
| 354 | if (stage == Stage::Fragment) { | 353 | if (stage == Stage::Fragment) { |
| 355 | for (size_t i = 0; i < 8; ++i) { | 354 | for (u32 index = 0; index < 8; ++index) { |
| 356 | if (!info.stores_frag_color[i]) { | 355 | if (!info.stores_frag_color[index]) { |
| 357 | continue; | 356 | continue; |
| 358 | } | 357 | } |
| 359 | frag_color[i] = DefineOutput(*this, F32[4]); | 358 | frag_color[index] = DefineOutput(*this, F32[4]); |
| 360 | Decorate(frag_color[i], spv::Decoration::Location, static_cast<u32>(i)); | 359 | Decorate(frag_color[index], spv::Decoration::Location, index); |
| 361 | Name(frag_color[i], fmt::format("frag_color{}", i)); | 360 | Name(frag_color[index], fmt::format("frag_color{}", index)); |
| 362 | } | 361 | } |
| 363 | if (!info.stores_frag_depth) { | 362 | if (info.stores_frag_depth) { |
| 364 | return; | 363 | frag_depth = DefineOutput(*this, F32[1]); |
| 364 | Decorate(frag_depth, spv::Decoration::BuiltIn, spv::BuiltIn::FragDepth); | ||
| 365 | Name(frag_depth, "frag_depth"); | ||
| 365 | } | 366 | } |
| 366 | frag_depth = DefineOutput(*this, F32[1]); | ||
| 367 | Decorate(frag_depth, spv::Decoration::BuiltIn, static_cast<u32>(spv::BuiltIn::FragDepth)); | ||
| 368 | Name(frag_depth, "frag_depth"); | ||
| 369 | } | 367 | } |
| 370 | } | 368 | } |
| 371 | 369 | ||
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 0a1e85408..5ed815c06 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -65,7 +65,6 @@ public: | |||
| 65 | VectorTypes U32; | 65 | VectorTypes U32; |
| 66 | VectorTypes F16; | 66 | VectorTypes F16; |
| 67 | VectorTypes F64; | 67 | VectorTypes F64; |
| 68 | Id array_U32x2; | ||
| 69 | 68 | ||
| 70 | Id true_value{}; | 69 | Id true_value{}; |
| 71 | Id false_value{}; | 70 | Id false_value{}; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index cc02f53f1..4da1f3707 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -95,7 +95,7 @@ void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Va | |||
| 95 | Id value); | 95 | Id value); |
| 96 | void EmitWriteStorage128(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | 96 | void EmitWriteStorage128(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 97 | Id value); | 97 | Id value); |
| 98 | Id EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2); | 98 | Id EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2); |
| 99 | Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3); | 99 | Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3); |
| 100 | Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); | 100 | Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); |
| 101 | Id EmitCompositeExtractU32x2(EmitContext& ctx, Id composite, u32 index); | 101 | Id EmitCompositeExtractU32x2(EmitContext& ctx, Id composite, u32 index); |
| @@ -104,7 +104,7 @@ Id EmitCompositeExtractU32x4(EmitContext& ctx, Id composite, u32 index); | |||
| 104 | Id EmitCompositeInsertU32x2(EmitContext& ctx, Id composite, Id object, u32 index); | 104 | Id EmitCompositeInsertU32x2(EmitContext& ctx, Id composite, Id object, u32 index); |
| 105 | Id EmitCompositeInsertU32x3(EmitContext& ctx, Id composite, Id object, u32 index); | 105 | Id EmitCompositeInsertU32x3(EmitContext& ctx, Id composite, Id object, u32 index); |
| 106 | Id EmitCompositeInsertU32x4(EmitContext& ctx, Id composite, Id object, u32 index); | 106 | Id EmitCompositeInsertU32x4(EmitContext& ctx, Id composite, Id object, u32 index); |
| 107 | Id EmitCompositeConstructF16x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2); | 107 | Id EmitCompositeConstructF16x2(EmitContext& ctx, Id e1, Id e2); |
| 108 | Id EmitCompositeConstructF16x3(EmitContext& ctx, Id e1, Id e2, Id e3); | 108 | Id EmitCompositeConstructF16x3(EmitContext& ctx, Id e1, Id e2, Id e3); |
| 109 | Id EmitCompositeConstructF16x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); | 109 | Id EmitCompositeConstructF16x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); |
| 110 | Id EmitCompositeExtractF16x2(EmitContext& ctx, Id composite, u32 index); | 110 | Id EmitCompositeExtractF16x2(EmitContext& ctx, Id composite, u32 index); |
| @@ -113,7 +113,7 @@ Id EmitCompositeExtractF16x4(EmitContext& ctx, Id composite, u32 index); | |||
| 113 | Id EmitCompositeInsertF16x2(EmitContext& ctx, Id composite, Id object, u32 index); | 113 | Id EmitCompositeInsertF16x2(EmitContext& ctx, Id composite, Id object, u32 index); |
| 114 | Id EmitCompositeInsertF16x3(EmitContext& ctx, Id composite, Id object, u32 index); | 114 | Id EmitCompositeInsertF16x3(EmitContext& ctx, Id composite, Id object, u32 index); |
| 115 | Id EmitCompositeInsertF16x4(EmitContext& ctx, Id composite, Id object, u32 index); | 115 | Id EmitCompositeInsertF16x4(EmitContext& ctx, Id composite, Id object, u32 index); |
| 116 | Id EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2); | 116 | Id EmitCompositeConstructF32x2(EmitContext& ctx, Id e1, Id e2); |
| 117 | Id EmitCompositeConstructF32x3(EmitContext& ctx, Id e1, Id e2, Id e3); | 117 | Id EmitCompositeConstructF32x3(EmitContext& ctx, Id e1, Id e2, Id e3); |
| 118 | Id EmitCompositeConstructF32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); | 118 | Id EmitCompositeConstructF32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); |
| 119 | Id EmitCompositeExtractF32x2(EmitContext& ctx, Id composite, u32 index); | 119 | Id EmitCompositeExtractF32x2(EmitContext& ctx, Id composite, u32 index); |
| @@ -122,7 +122,6 @@ Id EmitCompositeExtractF32x4(EmitContext& ctx, Id composite, u32 index); | |||
| 122 | Id EmitCompositeInsertF32x2(EmitContext& ctx, Id composite, Id object, u32 index); | 122 | Id EmitCompositeInsertF32x2(EmitContext& ctx, Id composite, Id object, u32 index); |
| 123 | Id EmitCompositeInsertF32x3(EmitContext& ctx, Id composite, Id object, u32 index); | 123 | Id EmitCompositeInsertF32x3(EmitContext& ctx, Id composite, Id object, u32 index); |
| 124 | Id EmitCompositeInsertF32x4(EmitContext& ctx, Id composite, Id object, u32 index); | 124 | Id EmitCompositeInsertF32x4(EmitContext& ctx, Id composite, Id object, u32 index); |
| 125 | Id EmitCompositeConstructArrayU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3, Id e4); | ||
| 126 | void EmitCompositeConstructF64x2(EmitContext& ctx); | 125 | void EmitCompositeConstructF64x2(EmitContext& ctx); |
| 127 | void EmitCompositeConstructF64x3(EmitContext& ctx); | 126 | void EmitCompositeConstructF64x3(EmitContext& ctx); |
| 128 | void EmitCompositeConstructF64x4(EmitContext& ctx); | 127 | void EmitCompositeConstructF64x4(EmitContext& ctx); |
| @@ -359,10 +358,10 @@ Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va | |||
| 359 | Id coords, Id dref, Id bias_lc, Id offset); | 358 | Id coords, Id dref, Id bias_lc, Id offset); |
| 360 | Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, | 359 | Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, |
| 361 | Id coords, Id dref, Id lod_lc, Id offset); | 360 | Id coords, Id dref, Id lod_lc, Id offset); |
| 362 | Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | 361 | Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| 363 | Id offset2); | 362 | const IR::Value& offset, const IR::Value& offset2); |
| 364 | Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 363 | Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| 365 | Id offset, Id offset2, Id dref); | 364 | const IR::Value& offset, const IR::Value& offset2, Id dref); |
| 366 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | 365 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, |
| 367 | Id lod, Id ms); | 366 | Id lod, Id ms); |
| 368 | Id EmitVoteAll(EmitContext& ctx, Id pred); | 367 | Id EmitVoteAll(EmitContext& ctx, Id pred); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp index f01d69d91..079e226de 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_composite.cpp | |||
| @@ -7,11 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | namespace Shader::Backend::SPIRV { | 8 | namespace Shader::Backend::SPIRV { |
| 9 | 9 | ||
| 10 | Id EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2) { | 10 | Id EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2) { |
| 11 | const auto info{inst->Flags<IR::CompositeDecoration>()}; | ||
| 12 | if (info.is_constant) { | ||
| 13 | return ctx.ConstantComposite(ctx.U32[2], e1, e2); | ||
| 14 | } | ||
| 15 | return ctx.OpCompositeConstruct(ctx.U32[2], e1, e2); | 11 | return ctx.OpCompositeConstruct(ctx.U32[2], e1, e2); |
| 16 | } | 12 | } |
| 17 | 13 | ||
| @@ -47,12 +43,7 @@ Id EmitCompositeInsertU32x4(EmitContext& ctx, Id composite, Id object, u32 index | |||
| 47 | return ctx.OpCompositeInsert(ctx.U32[4], object, composite, index); | 43 | return ctx.OpCompositeInsert(ctx.U32[4], object, composite, index); |
| 48 | } | 44 | } |
| 49 | 45 | ||
| 50 | Id EmitCompositeConstructF16x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2) { | 46 | Id EmitCompositeConstructF16x2(EmitContext& ctx, Id e1, Id e2) { |
| 51 | |||
| 52 | const auto info{inst->Flags<IR::CompositeDecoration>()}; | ||
| 53 | if (info.is_constant) { | ||
| 54 | return ctx.ConstantComposite(ctx.F16[2], e1, e2); | ||
| 55 | } | ||
| 56 | return ctx.OpCompositeConstruct(ctx.F16[2], e1, e2); | 47 | return ctx.OpCompositeConstruct(ctx.F16[2], e1, e2); |
| 57 | } | 48 | } |
| 58 | 49 | ||
| @@ -88,11 +79,7 @@ Id EmitCompositeInsertF16x4(EmitContext& ctx, Id composite, Id object, u32 index | |||
| 88 | return ctx.OpCompositeInsert(ctx.F16[4], object, composite, index); | 79 | return ctx.OpCompositeInsert(ctx.F16[4], object, composite, index); |
| 89 | } | 80 | } |
| 90 | 81 | ||
| 91 | Id EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2) { | 82 | Id EmitCompositeConstructF32x2(EmitContext& ctx, Id e1, Id e2) { |
| 92 | const auto info{inst->Flags<IR::CompositeDecoration>()}; | ||
| 93 | if (info.is_constant) { | ||
| 94 | return ctx.ConstantComposite(ctx.F32[2], e1, e2); | ||
| 95 | } | ||
| 96 | return ctx.OpCompositeConstruct(ctx.F32[2], e1, e2); | 83 | return ctx.OpCompositeConstruct(ctx.F32[2], e1, e2); |
| 97 | } | 84 | } |
| 98 | 85 | ||
| @@ -164,15 +151,4 @@ Id EmitCompositeInsertF64x4(EmitContext& ctx, Id composite, Id object, u32 index | |||
| 164 | return ctx.OpCompositeInsert(ctx.F64[4], object, composite, index); | 151 | return ctx.OpCompositeInsert(ctx.F64[4], object, composite, index); |
| 165 | } | 152 | } |
| 166 | 153 | ||
| 167 | Id EmitCompositeConstructArrayU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3, Id e4) { | ||
| 168 | const auto info{inst->Flags<IR::CompositeDecoration>()}; | ||
| 169 | if (info.is_constant) { | ||
| 170 | return ctx.ConstantComposite(ctx.array_U32x2, e1, e2, e3, e4); | ||
| 171 | } | ||
| 172 | if (ctx.profile.support_variadic_ptp) { | ||
| 173 | return ctx.OpCompositeConstruct(ctx.array_U32x2, e1, e2, e3, e4); | ||
| 174 | } | ||
| 175 | return {}; | ||
| 176 | } | ||
| 177 | |||
| 178 | } // namespace Shader::Backend::SPIRV | 154 | } // namespace Shader::Backend::SPIRV |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 13bc8831f..b6e9d3c0c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp | |||
| @@ -30,16 +30,34 @@ public: | |||
| 30 | } | 30 | } |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | explicit ImageOperands([[maybe_unused]] EmitContext& ctx, Id offset, Id offset2) { | 33 | explicit ImageOperands(EmitContext& ctx, const IR::Value& offset, const IR::Value& offset2) { |
| 34 | if (Sirit::ValidId(offset)) { | 34 | if (offset2.IsEmpty()) { |
| 35 | Add(spv::ImageOperandsMask::Offset, offset); | 35 | if (offset.IsEmpty()) { |
| 36 | return; | ||
| 37 | } | ||
| 38 | Add(spv::ImageOperandsMask::Offset, ctx.Def(offset)); | ||
| 39 | return; | ||
| 40 | } | ||
| 41 | const std::array values{offset.InstRecursive(), offset2.InstRecursive()}; | ||
| 42 | if (!values[0]->AreAllArgsImmediates() || !values[1]->AreAllArgsImmediates()) { | ||
| 43 | throw NotImplementedException("Not all arguments in PTP are immediate"); | ||
| 36 | } | 44 | } |
| 37 | if (Sirit::ValidId(offset2)) { | 45 | const IR::Opcode opcode{values[0]->Opcode()}; |
| 38 | Add(spv::ImageOperandsMask::ConstOffsets, offset2); | 46 | if (opcode != values[1]->Opcode() || opcode != IR::Opcode::CompositeConstructU32x4) { |
| 47 | throw LogicError("Invalid PTP arguments"); | ||
| 39 | } | 48 | } |
| 49 | auto read{[&](int a, int b) { return ctx.Constant(ctx.U32[1], values[a]->Arg(b).U32()); }}; | ||
| 50 | |||
| 51 | const Id offsets{ | ||
| 52 | ctx.ConstantComposite(ctx.TypeArray(ctx.U32[2], ctx.Constant(ctx.U32[1], 4)), | ||
| 53 | ctx.ConstantComposite(ctx.U32[2], read(0, 0), read(0, 1)), | ||
| 54 | ctx.ConstantComposite(ctx.U32[2], read(0, 2), read(0, 3)), | ||
| 55 | ctx.ConstantComposite(ctx.U32[2], read(1, 0), read(1, 1)), | ||
| 56 | ctx.ConstantComposite(ctx.U32[2], read(1, 2), read(1, 3)))}; | ||
| 57 | Add(spv::ImageOperandsMask::ConstOffsets, offsets); | ||
| 40 | } | 58 | } |
| 41 | 59 | ||
| 42 | explicit ImageOperands([[maybe_unused]] EmitContext& ctx, Id offset, Id lod, Id ms) { | 60 | explicit ImageOperands(Id offset, Id lod, Id ms) { |
| 43 | if (Sirit::ValidId(lod)) { | 61 | if (Sirit::ValidId(lod)) { |
| 44 | Add(spv::ImageOperandsMask::Lod, lod); | 62 | Add(spv::ImageOperandsMask::Lod, lod); |
| 45 | } | 63 | } |
| @@ -197,8 +215,8 @@ Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Va | |||
| 197 | Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); | 215 | Texture(ctx, index), coords, dref, operands.Mask(), operands.Span()); |
| 198 | } | 216 | } |
| 199 | 217 | ||
| 200 | Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | 218 | Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| 201 | Id offset2) { | 219 | const IR::Value& offset, const IR::Value& offset2) { |
| 202 | const auto info{inst->Flags<IR::TextureInstInfo>()}; | 220 | const auto info{inst->Flags<IR::TextureInstInfo>()}; |
| 203 | const ImageOperands operands(ctx, offset, offset2); | 221 | const ImageOperands operands(ctx, offset, offset2); |
| 204 | return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst, | 222 | return Emit(&EmitContext::OpImageSparseGather, &EmitContext::OpImageGather, ctx, inst, |
| @@ -208,7 +226,7 @@ Id EmitImageGather(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id | |||
| 208 | } | 226 | } |
| 209 | 227 | ||
| 210 | Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, | 228 | Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, |
| 211 | Id offset, Id offset2, Id dref) { | 229 | const IR::Value& offset, const IR::Value& offset2, Id dref) { |
| 212 | const auto info{inst->Flags<IR::TextureInstInfo>()}; | 230 | const auto info{inst->Flags<IR::TextureInstInfo>()}; |
| 213 | const ImageOperands operands(ctx, offset, offset2); | 231 | const ImageOperands operands(ctx, offset, offset2); |
| 214 | return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst, | 232 | return Emit(&EmitContext::OpImageSparseDrefGather, &EmitContext::OpImageDrefGather, ctx, inst, |
| @@ -218,7 +236,7 @@ Id EmitImageGatherDref(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, | |||
| 218 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, | 236 | Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id offset, |
| 219 | Id lod, Id ms) { | 237 | Id lod, Id ms) { |
| 220 | const auto info{inst->Flags<IR::TextureInstInfo>()}; | 238 | const auto info{inst->Flags<IR::TextureInstInfo>()}; |
| 221 | const ImageOperands operands(ctx, offset, lod, ms); | 239 | const ImageOperands operands(offset, lod, ms); |
| 222 | return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], | 240 | return Emit(&EmitContext::OpImageSparseFetch, &EmitContext::OpImageFetch, ctx, inst, ctx.F32[4], |
| 223 | Texture(ctx, index), coords, operands.Mask(), operands.Span()); | 241 | Texture(ctx, index), coords, operands.Mask(), operands.Span()); |
| 224 | } | 242 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index b8d36f362..0296f8773 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -398,16 +398,15 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2) { | |||
| 398 | if (e1.Type() != e2.Type()) { | 398 | if (e1.Type() != e2.Type()) { |
| 399 | throw InvalidArgument("Mismatching types {} and {}", e1.Type(), e2.Type()); | 399 | throw InvalidArgument("Mismatching types {} and {}", e1.Type(), e2.Type()); |
| 400 | } | 400 | } |
| 401 | CompositeDecoration decor{}; | ||
| 402 | switch (e1.Type()) { | 401 | switch (e1.Type()) { |
| 403 | case Type::U32: | 402 | case Type::U32: |
| 404 | return Inst(Opcode::CompositeConstructU32x2, Flags{decor}, e1, e2); | 403 | return Inst(Opcode::CompositeConstructU32x2, e1, e2); |
| 405 | case Type::F16: | 404 | case Type::F16: |
| 406 | return Inst(Opcode::CompositeConstructF16x2, Flags{decor}, e1, e2); | 405 | return Inst(Opcode::CompositeConstructF16x2, e1, e2); |
| 407 | case Type::F32: | 406 | case Type::F32: |
| 408 | return Inst(Opcode::CompositeConstructF32x2, Flags{decor}, e1, e2); | 407 | return Inst(Opcode::CompositeConstructF32x2, e1, e2); |
| 409 | case Type::F64: | 408 | case Type::F64: |
| 410 | return Inst(Opcode::CompositeConstructF64x2, Flags{decor}, e1, e2); | 409 | return Inst(Opcode::CompositeConstructF64x2, e1, e2); |
| 411 | default: | 410 | default: |
| 412 | ThrowInvalidType(e1.Type()); | 411 | ThrowInvalidType(e1.Type()); |
| 413 | } | 412 | } |
| @@ -437,7 +436,6 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Valu | |||
| 437 | throw InvalidArgument("Mismatching types {}, {}, {}, and {}", e1.Type(), e2.Type(), | 436 | throw InvalidArgument("Mismatching types {}, {}, {}, and {}", e1.Type(), e2.Type(), |
| 438 | e3.Type(), e4.Type()); | 437 | e3.Type(), e4.Type()); |
| 439 | } | 438 | } |
| 440 | CompositeDecoration decor{}; | ||
| 441 | switch (e1.Type()) { | 439 | switch (e1.Type()) { |
| 442 | case Type::U32: | 440 | case Type::U32: |
| 443 | return Inst(Opcode::CompositeConstructU32x4, e1, e2, e3, e4); | 441 | return Inst(Opcode::CompositeConstructU32x4, e1, e2, e3, e4); |
| @@ -447,8 +445,6 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Valu | |||
| 447 | return Inst(Opcode::CompositeConstructF32x4, e1, e2, e3, e4); | 445 | return Inst(Opcode::CompositeConstructF32x4, e1, e2, e3, e4); |
| 448 | case Type::F64: | 446 | case Type::F64: |
| 449 | return Inst(Opcode::CompositeConstructF64x4, e1, e2, e3, e4); | 447 | return Inst(Opcode::CompositeConstructF64x4, e1, e2, e3, e4); |
| 450 | case Type::U32x2: | ||
| 451 | return Inst(Opcode::CompositeConstructArrayU32x2, Flags{decor}, e1, e2, e3, e4); | ||
| 452 | default: | 448 | default: |
| 453 | ThrowInvalidType(e1.Type()); | 449 | ThrowInvalidType(e1.Type()); |
| 454 | } | 450 | } |
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.h b/src/shader_recompiler/frontend/ir/microinstruction.h index 77296cfa4..6658dc674 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.h +++ b/src/shader_recompiler/frontend/ir/microinstruction.h | |||
| @@ -101,8 +101,8 @@ public: | |||
| 101 | 101 | ||
| 102 | template <typename FlagsType> | 102 | template <typename FlagsType> |
| 103 | requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>) | 103 | requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>) |
| 104 | [[nodiscard]] void SetFlags(FlagsType& new_val) noexcept { | 104 | [[nodiscard]] void SetFlags(FlagsType value) noexcept { |
| 105 | std::memcpy(&flags, &new_val, sizeof(new_val)); | 105 | std::memcpy(&flags, &value, sizeof(value)); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | /// Intrusively store the host definition of this instruction. | 108 | /// Intrusively store the host definition of this instruction. |
diff --git a/src/shader_recompiler/frontend/ir/modifiers.h b/src/shader_recompiler/frontend/ir/modifiers.h index 20fb14fea..4f09a4b39 100644 --- a/src/shader_recompiler/frontend/ir/modifiers.h +++ b/src/shader_recompiler/frontend/ir/modifiers.h | |||
| @@ -32,11 +32,6 @@ struct FpControl { | |||
| 32 | }; | 32 | }; |
| 33 | static_assert(sizeof(FpControl) <= sizeof(u32)); | 33 | static_assert(sizeof(FpControl) <= sizeof(u32)); |
| 34 | 34 | ||
| 35 | struct CompositeDecoration { | ||
| 36 | bool is_constant{false}; | ||
| 37 | }; | ||
| 38 | static_assert(sizeof(CompositeDecoration) <= sizeof(u32)); | ||
| 39 | |||
| 40 | union TextureInstInfo { | 35 | union TextureInstInfo { |
| 41 | u32 raw; | 36 | u32 raw; |
| 42 | BitField<0, 8, TextureType> type; | 37 | BitField<0, 8, TextureType> type; |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 3dacd7b6b..e12b92c47 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -126,7 +126,6 @@ OPCODE(CompositeExtractF64x4, F64, F64x | |||
| 126 | OPCODE(CompositeInsertF64x2, F64x2, F64x2, F64, U32, ) | 126 | OPCODE(CompositeInsertF64x2, F64x2, F64x2, F64, U32, ) |
| 127 | OPCODE(CompositeInsertF64x3, F64x3, F64x3, F64, U32, ) | 127 | OPCODE(CompositeInsertF64x3, F64x3, F64x3, F64, U32, ) |
| 128 | OPCODE(CompositeInsertF64x4, F64x4, F64x4, F64, U32, ) | 128 | OPCODE(CompositeInsertF64x4, F64x4, F64x4, F64, U32, ) |
| 129 | OPCODE(CompositeConstructArrayU32x2, Opaque, U32x2, U32x2, U32x2, U32x2, ) | ||
| 130 | 129 | ||
| 131 | // Select operations | 130 | // Select operations |
| 132 | OPCODE(SelectU1, U1, U1, U1, U1, ) | 131 | OPCODE(SelectU1, U1, U1, U1, U1, ) |
diff --git a/src/shader_recompiler/frontend/ir/value.cpp b/src/shader_recompiler/frontend/ir/value.cpp index 7671fc3d8..e8e4662e7 100644 --- a/src/shader_recompiler/frontend/ir/value.cpp +++ b/src/shader_recompiler/frontend/ir/value.cpp | |||
| @@ -44,20 +44,6 @@ bool Value::IsEmpty() const noexcept { | |||
| 44 | return type == Type::Void; | 44 | return type == Type::Void; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | bool Value::IsConstantContainer() const { | ||
| 48 | if (IsImmediate()) { | ||
| 49 | return true; | ||
| 50 | } | ||
| 51 | ValidateAccess(Type::Opaque); | ||
| 52 | auto num_args = inst->NumArgs(); | ||
| 53 | for (size_t i = 0; i < num_args; i++) { | ||
| 54 | if (!inst->Arg(i).IsConstantContainer()) { | ||
| 55 | return false; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | return true; | ||
| 59 | } | ||
| 60 | |||
| 61 | bool Value::IsImmediate() const noexcept { | 47 | bool Value::IsImmediate() const noexcept { |
| 62 | if (IsIdentity()) { | 48 | if (IsIdentity()) { |
| 63 | return inst->Arg(0).IsImmediate(); | 49 | return inst->Arg(0).IsImmediate(); |
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h index 5d6e74c14..b27601e70 100644 --- a/src/shader_recompiler/frontend/ir/value.h +++ b/src/shader_recompiler/frontend/ir/value.h | |||
| @@ -38,7 +38,6 @@ public: | |||
| 38 | [[nodiscard]] bool IsImmediate() const noexcept; | 38 | [[nodiscard]] bool IsImmediate() const noexcept; |
| 39 | [[nodiscard]] bool IsLabel() const noexcept; | 39 | [[nodiscard]] bool IsLabel() const noexcept; |
| 40 | [[nodiscard]] IR::Type Type() const noexcept; | 40 | [[nodiscard]] IR::Type Type() const noexcept; |
| 41 | [[nodiscard]] bool IsConstantContainer() const; | ||
| 42 | 41 | ||
| 43 | [[nodiscard]] IR::Inst* Inst() const; | 42 | [[nodiscard]] IR::Inst* Inst() const; |
| 44 | [[nodiscard]] IR::Block* Label() const; | 43 | [[nodiscard]] IR::Block* Label() const; |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather.cpp index cdf5cb5c4..b2f9cda46 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_gather.cpp | |||
| @@ -106,17 +106,17 @@ IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg& reg, TextureType type) { | |||
| 106 | throw NotImplementedException("Invalid texture type {}", type); | 106 | throw NotImplementedException("Invalid texture type {}", type); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | IR::Value MakeOffsetPTP(TranslatorVisitor& v, IR::Reg& reg) { | 109 | std::pair<IR::Value, IR::Value> MakeOffsetPTP(TranslatorVisitor& v, IR::Reg& reg) { |
| 110 | const IR::U32 value1{v.X(reg++)}; | 110 | const IR::U32 value1{v.X(reg++)}; |
| 111 | const IR::U32 value2{v.X(reg++)}; | 111 | const IR::U32 value2{v.X(reg++)}; |
| 112 | const IR::U32 bitsize = v.ir.Imm32(6); | 112 | const IR::U32 bitsize{v.ir.Imm32(6)}; |
| 113 | const auto getVector = ([&v, &bitsize](const IR::U32& value, u32 base) { | 113 | const auto make_vector{[&v, &bitsize](const IR::U32& value) { |
| 114 | return v.ir.CompositeConstruct( | 114 | return v.ir.CompositeConstruct(v.ir.BitFieldExtract(value, v.ir.Imm32(0), bitsize, true), |
| 115 | v.ir.BitFieldExtract(value, v.ir.Imm32(base + 0), bitsize, true), | 115 | v.ir.BitFieldExtract(value, v.ir.Imm32(8), bitsize, true), |
| 116 | v.ir.BitFieldExtract(value, v.ir.Imm32(base + 8), bitsize, true)); | 116 | v.ir.BitFieldExtract(value, v.ir.Imm32(16), bitsize, true), |
| 117 | }); | 117 | v.ir.BitFieldExtract(value, v.ir.Imm32(24), bitsize, true)); |
| 118 | return v.ir.CompositeConstruct(getVector(value1, 0), getVector(value1, 16), | 118 | }}; |
| 119 | getVector(value2, 0), getVector(value2, 16)); | 119 | return {make_vector(value1), make_vector(value2)}; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | void Impl(TranslatorVisitor& v, u64 insn, ComponentType component_type, OffsetType offset_type, | 122 | void Impl(TranslatorVisitor& v, u64 insn, ComponentType component_type, OffsetType offset_type, |
| @@ -150,14 +150,12 @@ void Impl(TranslatorVisitor& v, u64 insn, ComponentType component_type, OffsetTy | |||
| 150 | switch (offset_type) { | 150 | switch (offset_type) { |
| 151 | case OffsetType::None: | 151 | case OffsetType::None: |
| 152 | break; | 152 | break; |
| 153 | case OffsetType::AOFFI: { | 153 | case OffsetType::AOFFI: |
| 154 | offset = MakeOffset(v, meta_reg, tld4.type); | 154 | offset = MakeOffset(v, meta_reg, tld4.type); |
| 155 | break; | 155 | break; |
| 156 | } | 156 | case OffsetType::PTP: |
| 157 | case OffsetType::PTP: { | 157 | std::tie(offset, offset2) = MakeOffsetPTP(v, meta_reg); |
| 158 | offset2 = MakeOffsetPTP(v, meta_reg); | ||
| 159 | break; | 158 | break; |
| 160 | } | ||
| 161 | default: | 159 | default: |
| 162 | throw NotImplementedException("Invalid offset type {}", offset_type); | 160 | throw NotImplementedException("Invalid offset type {}", offset_type); |
| 163 | } | 161 | } |
| @@ -167,7 +165,7 @@ void Impl(TranslatorVisitor& v, u64 insn, ComponentType component_type, OffsetTy | |||
| 167 | IR::TextureInstInfo info{}; | 165 | IR::TextureInstInfo info{}; |
| 168 | info.type.Assign(GetType(tld4.type, tld4.dc != 0)); | 166 | info.type.Assign(GetType(tld4.type, tld4.dc != 0)); |
| 169 | info.gather_component.Assign(static_cast<u32>(component_type)); | 167 | info.gather_component.Assign(static_cast<u32>(component_type)); |
| 170 | const IR::Value sample{[&]() -> IR::Value { | 168 | const IR::Value sample{[&] { |
| 171 | if (tld4.dc == 0) { | 169 | if (tld4.dc == 0) { |
| 172 | return v.ir.ImageGather(handle, coords, offset, offset2, info); | 170 | return v.ir.ImageGather(handle, coords, offset, offset2, info); |
| 173 | } | 171 | } |
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index 12159e738..052f1609b 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -355,17 +355,6 @@ void FoldBranchConditional(IR::Inst& inst) { | |||
| 355 | } | 355 | } |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | void FoldConstantComposite(IR::Inst& inst, size_t amount = 2) { | ||
| 359 | for (size_t i = 0; i < amount; i++) { | ||
| 360 | if (!inst.Arg(i).IsConstantContainer()) { | ||
| 361 | return; | ||
| 362 | } | ||
| 363 | } | ||
| 364 | auto info{inst.Flags<IR::CompositeDecoration>()}; | ||
| 365 | info.is_constant = true; | ||
| 366 | inst.SetFlags(info); | ||
| 367 | } | ||
| 368 | |||
| 369 | void ConstantPropagation(IR::Block& block, IR::Inst& inst) { | 358 | void ConstantPropagation(IR::Block& block, IR::Inst& inst) { |
| 370 | switch (inst.Opcode()) { | 359 | switch (inst.Opcode()) { |
| 371 | case IR::Opcode::GetRegister: | 360 | case IR::Opcode::GetRegister: |
| @@ -391,13 +380,6 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) { | |||
| 391 | case IR::Opcode::SelectF32: | 380 | case IR::Opcode::SelectF32: |
| 392 | case IR::Opcode::SelectF64: | 381 | case IR::Opcode::SelectF64: |
| 393 | return FoldSelect(inst); | 382 | return FoldSelect(inst); |
| 394 | case IR::Opcode::CompositeConstructU32x2: | ||
| 395 | case IR::Opcode::CompositeConstructF16x2: | ||
| 396 | case IR::Opcode::CompositeConstructF32x2: | ||
| 397 | case IR::Opcode::CompositeConstructF64x2: | ||
| 398 | return FoldConstantComposite(inst, 2); | ||
| 399 | case IR::Opcode::CompositeConstructArrayU32x2: | ||
| 400 | return FoldConstantComposite(inst, 4); | ||
| 401 | case IR::Opcode::FPMul32: | 383 | case IR::Opcode::FPMul32: |
| 402 | return FoldFPMul32(inst); | 384 | return FoldFPMul32(inst); |
| 403 | case IR::Opcode::LogicalAnd: | 385 | case IR::Opcode::LogicalAnd: |
| @@ -423,12 +405,12 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) { | |||
| 423 | return; | 405 | return; |
| 424 | case IR::Opcode::BitFieldSExtract: | 406 | case IR::Opcode::BitFieldSExtract: |
| 425 | FoldWhenAllImmediates(inst, [](s32 base, u32 shift, u32 count) { | 407 | FoldWhenAllImmediates(inst, [](s32 base, u32 shift, u32 count) { |
| 426 | const size_t back_shift = static_cast<size_t>(shift) + static_cast<size_t>(count); | 408 | const size_t back_shift{static_cast<size_t>(shift) + static_cast<size_t>(count)}; |
| 427 | if (back_shift > Common::BitSize<s32>()) { | 409 | if (back_shift > Common::BitSize<s32>()) { |
| 428 | throw LogicError("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldSExtract, | 410 | throw LogicError("Undefined result in {}({}, {}, {})", IR::Opcode::BitFieldSExtract, |
| 429 | base, shift, count); | 411 | base, shift, count); |
| 430 | } | 412 | } |
| 431 | const size_t left_shift = Common::BitSize<s32>() - back_shift; | 413 | const size_t left_shift{Common::BitSize<s32>() - back_shift}; |
| 432 | return static_cast<u32>(static_cast<s32>(base << left_shift) >> | 414 | return static_cast<u32>(static_cast<s32>(base << left_shift) >> |
| 433 | static_cast<size_t>(Common::BitSize<s32>() - count)); | 415 | static_cast<size_t>(Common::BitSize<s32>() - count)); |
| 434 | }); | 416 | }); |
diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index 64031f49c..41550bfc6 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h | |||
| @@ -30,7 +30,6 @@ struct Profile { | |||
| 30 | bool support_fp32_signed_zero_nan_preserve{}; | 30 | bool support_fp32_signed_zero_nan_preserve{}; |
| 31 | bool support_fp64_signed_zero_nan_preserve{}; | 31 | bool support_fp64_signed_zero_nan_preserve{}; |
| 32 | bool support_vote{}; | 32 | bool support_vote{}; |
| 33 | bool support_variadic_ptp{}; | ||
| 34 | bool warp_size_potentially_larger_than_guest{}; | 33 | bool warp_size_potentially_larger_than_guest{}; |
| 35 | 34 | ||
| 36 | // FClamp is broken and OpFMax + OpFMin should be used instead | 35 | // FClamp is broken and OpFMax + OpFMin should be used instead |