glasm: Fix potential aliasing bug on cube array samples
This commit is contained in:
		| @@ -268,9 +268,16 @@ void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Valu | ||||
| } | ||||
|  | ||||
| void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                                     const IR::Value& coord, ScalarF32 dref, Register bias_lc, | ||||
|                                     const IR::Value& offset) { | ||||
|                                     const IR::Value& coord, const IR::Value& dref, | ||||
|                                     const IR::Value& bias_lc, const IR::Value& offset) { | ||||
|     // Allocate early to avoid aliases | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     ScopedRegister staging; | ||||
|     if (info.type == TextureType::ColorArrayCube) { | ||||
|         staging = ScopedRegister{ctx.reg_alloc}; | ||||
|     } | ||||
|     const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)}; | ||||
|     const Register bias_lc_vec{ctx.reg_alloc.Consume(bias_lc)}; | ||||
|     const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; | ||||
|     const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; | ||||
|     const std::string_view type{TextureType(info)}; | ||||
| @@ -287,14 +294,14 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR:: | ||||
|                 ctx.Add("MOV.F {}.z,{};" | ||||
|                         "MOV.F {}.w,{}.x;" | ||||
|                         "TXB.F.LODCLAMP{} {},{},{}.y,{},{}{};", | ||||
|                         coord_vec, dref, coord_vec, bias_lc, sparse_mod, ret, coord_vec, bias_lc, | ||||
|                         texture, type, offset_vec); | ||||
|                         coord_vec, dref_val, coord_vec, bias_lc_vec, sparse_mod, ret, coord_vec, | ||||
|                         bias_lc_vec, texture, type, offset_vec); | ||||
|                 break; | ||||
|             case TextureType::ColorArray2D: | ||||
|             case TextureType::ColorCube: | ||||
|                 ctx.Add("MOV.F {}.w,{};" | ||||
|                         "TXB.F.LODCLAMP{} {},{},{},{},{}{};", | ||||
|                         coord_vec, dref, sparse_mod, ret, coord_vec, bias_lc, texture, type, | ||||
|                         coord_vec, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec, texture, type, | ||||
|                         offset_vec); | ||||
|                 break; | ||||
|             default: | ||||
| @@ -309,25 +316,23 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR:: | ||||
|                 ctx.Add("MOV.F {}.z,{};" | ||||
|                         "MOV.F {}.w,{}.x;" | ||||
|                         "TXB.F{} {},{},{},{}{};", | ||||
|                         coord_vec, dref, coord_vec, bias_lc, sparse_mod, ret, coord_vec, texture, | ||||
|                         type, offset_vec); | ||||
|                         coord_vec, dref_val, coord_vec, bias_lc_vec, sparse_mod, ret, coord_vec, | ||||
|                         texture, type, offset_vec); | ||||
|                 break; | ||||
|             case TextureType::ColorArray2D: | ||||
|             case TextureType::ColorCube: | ||||
|                 ctx.Add("MOV.F {}.w,{};" | ||||
|                         "TXB.F{} {},{},{},{},{}{};", | ||||
|                         coord_vec, dref, sparse_mod, ret, coord_vec, bias_lc, texture, type, | ||||
|                         coord_vec, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec, texture, type, | ||||
|                         offset_vec); | ||||
|                 break; | ||||
|             case TextureType::ColorArrayCube: { | ||||
|                 const ScopedRegister pair{ctx.reg_alloc}; | ||||
|             case TextureType::ColorArrayCube: | ||||
|                 ctx.Add("MOV.F {}.x,{};" | ||||
|                         "MOV.F {}.y,{}.x;" | ||||
|                         "TXB.F{} {},{},{},{},{}{};", | ||||
|                         pair.reg, dref, pair.reg, bias_lc, sparse_mod, ret, coord_vec, pair.reg, | ||||
|                         texture, type, offset_vec); | ||||
|                         staging.reg, dref_val, staging.reg, bias_lc_vec, sparse_mod, ret, coord_vec, | ||||
|                         staging.reg, texture, type, offset_vec); | ||||
|                 break; | ||||
|             } | ||||
|             default: | ||||
|                 throw NotImplementedException("Invalid type {}", info.type.Value()); | ||||
|             } | ||||
| @@ -340,15 +345,14 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR:: | ||||
|                 const char dref_swizzle{w_swizzle ? 'w' : 'z'}; | ||||
|                 ctx.Add("MOV.F {}.{},{};" | ||||
|                         "TEX.F.LODCLAMP{} {},{},{},{},{}{};", | ||||
|                         coord_vec, dref_swizzle, dref, sparse_mod, ret, coord_vec, bias_lc, texture, | ||||
|                         type, offset_vec); | ||||
|                         coord_vec, dref_swizzle, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec, | ||||
|                         texture, type, offset_vec); | ||||
|             } else { | ||||
|                 const ScopedRegister pair{ctx.reg_alloc}; | ||||
|                 ctx.Add("MOV.F {}.x,{};" | ||||
|                         "MOV.F {}.y,{};" | ||||
|                         "TEX.F.LODCLAMP{} {},{},{},{},{}{};", | ||||
|                         pair.reg, dref, pair.reg, bias_lc, sparse_mod, ret, coord_vec, pair.reg, | ||||
|                         texture, type, offset_vec); | ||||
|                         staging.reg, dref_val, staging.reg, bias_lc_vec, sparse_mod, ret, coord_vec, | ||||
|                         staging.reg, texture, type, offset_vec); | ||||
|             } | ||||
|         } else { | ||||
|             if (info.type != TextureType::ColorArrayCube) { | ||||
| @@ -357,11 +361,10 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR:: | ||||
|                 const char dref_swizzle{w_swizzle ? 'w' : 'z'}; | ||||
|                 ctx.Add("MOV.F {}.{},{};" | ||||
|                         "TEX.F{} {},{},{},{}{};", | ||||
|                         coord_vec, dref_swizzle, dref, sparse_mod, ret, coord_vec, texture, type, | ||||
|                         offset_vec); | ||||
|                         coord_vec, dref_swizzle, dref_val, sparse_mod, ret, coord_vec, texture, | ||||
|                         type, offset_vec); | ||||
|             } else { | ||||
|                 const ScopedRegister pair{ctx.reg_alloc}; | ||||
|                 ctx.Add("TEX.F{} {},{},{},{},{}{};", sparse_mod, ret, coord_vec, dref, texture, | ||||
|                 ctx.Add("TEX.F{} {},{},{},{},{}{};", sparse_mod, ret, coord_vec, dref_val, texture, | ||||
|                         type, offset_vec); | ||||
|             } | ||||
|         } | ||||
| @@ -370,9 +373,16 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR:: | ||||
| } | ||||
|  | ||||
| void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                                     const IR::Value& coord, ScalarF32 dref, ScalarF32 lod, | ||||
|                                     const IR::Value& offset) { | ||||
|                                     const IR::Value& coord, const IR::Value& dref, | ||||
|                                     const IR::Value& lod, const IR::Value& offset) { | ||||
|     // Allocate early to avoid aliases | ||||
|     const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||||
|     ScopedRegister staging; | ||||
|     if (info.type == TextureType::ColorArrayCube) { | ||||
|         staging = ScopedRegister{ctx.reg_alloc}; | ||||
|     } | ||||
|     const ScalarF32 dref_val{ctx.reg_alloc.Consume(dref)}; | ||||
|     const ScalarF32 lod_val{ctx.reg_alloc.Consume(lod)}; | ||||
|     const auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)}; | ||||
|     const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""}; | ||||
|     const std::string_view type{TextureType(info)}; | ||||
| @@ -387,24 +397,23 @@ void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR:: | ||||
|         ctx.Add("MOV.F {}.z,{};" | ||||
|                 "MOV.F {}.w,{};" | ||||
|                 "TXL.F{} {},{},{},{}{};", | ||||
|                 coord_vec, dref, coord_vec, lod, sparse_mod, ret, coord_vec, texture, type, | ||||
|                 coord_vec, dref_val, coord_vec, lod_val, sparse_mod, ret, coord_vec, texture, type, | ||||
|                 offset_vec); | ||||
|         break; | ||||
|     case TextureType::ColorArray2D: | ||||
|     case TextureType::ColorCube: | ||||
|         ctx.Add("MOV.F {}.w,{};" | ||||
|                 "TXL.F{} {},{},{},{},{}{};", | ||||
|                 coord_vec, dref, sparse_mod, ret, coord_vec, lod, texture, type, offset_vec); | ||||
|                 coord_vec, dref_val, sparse_mod, ret, coord_vec, lod_val, texture, type, | ||||
|                 offset_vec); | ||||
|         break; | ||||
|     case TextureType::ColorArrayCube: { | ||||
|         const ScopedRegister pair{ctx.reg_alloc}; | ||||
|     case TextureType::ColorArrayCube: | ||||
|         ctx.Add("MOV.F {}.x,{};" | ||||
|                 "MOV.F {}.y,{};" | ||||
|                 "TXL.F{} {},{},{},{},{}{};", | ||||
|                 pair.reg, dref, pair.reg, lod, sparse_mod, ret, coord_vec, pair.reg, texture, type, | ||||
|                 offset_vec); | ||||
|                 staging.reg, dref_val, staging.reg, lod_val, sparse_mod, ret, coord_vec, | ||||
|                 staging.reg, texture, type, offset_vec); | ||||
|         break; | ||||
|     } | ||||
|     default: | ||||
|         throw NotImplementedException("Invalid type {}", info.type.Value()); | ||||
|     } | ||||
|   | ||||
| @@ -533,11 +533,11 @@ void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Valu | ||||
| void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                                 const IR::Value& coord, ScalarF32 lod, const IR::Value& offset); | ||||
| void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                                     const IR::Value& coord, ScalarF32 dref, Register bias_lc, | ||||
|                                     const IR::Value& offset); | ||||
|                                     const IR::Value& coord, const IR::Value& dref, | ||||
|                                     const IR::Value& bias_lc, const IR::Value& offset); | ||||
| void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                                     const IR::Value& coord, ScalarF32 dref, ScalarF32 lod, | ||||
|                                     const IR::Value& offset); | ||||
|                                     const IR::Value& coord, const IR::Value& dref, | ||||
|                                     const IR::Value& lod, const IR::Value& offset); | ||||
| void EmitImageGather(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|                      const IR::Value& coord, const IR::Value& offset, const IR::Value& offset2); | ||||
| void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user