glasm: Fix potential aliasing bug on cube array samples
This commit is contained in:
parent
8fdb00a2b5
commit
0a54291c9c
|
@ -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,
|
void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
||||||
const IR::Value& coord, ScalarF32 dref, Register bias_lc,
|
const IR::Value& coord, const IR::Value& dref,
|
||||||
const IR::Value& offset) {
|
const IR::Value& bias_lc, const IR::Value& offset) {
|
||||||
|
// Allocate early to avoid aliases
|
||||||
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
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 auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
|
||||||
const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
|
const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
|
||||||
const std::string_view type{TextureType(info)};
|
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,{};"
|
ctx.Add("MOV.F {}.z,{};"
|
||||||
"MOV.F {}.w,{}.x;"
|
"MOV.F {}.w,{}.x;"
|
||||||
"TXB.F.LODCLAMP{} {},{},{}.y,{},{}{};",
|
"TXB.F.LODCLAMP{} {},{},{}.y,{},{}{};",
|
||||||
coord_vec, dref, coord_vec, bias_lc, sparse_mod, ret, coord_vec, bias_lc,
|
coord_vec, dref_val, coord_vec, bias_lc_vec, sparse_mod, ret, coord_vec,
|
||||||
texture, type, offset_vec);
|
bias_lc_vec, texture, type, offset_vec);
|
||||||
break;
|
break;
|
||||||
case TextureType::ColorArray2D:
|
case TextureType::ColorArray2D:
|
||||||
case TextureType::ColorCube:
|
case TextureType::ColorCube:
|
||||||
ctx.Add("MOV.F {}.w,{};"
|
ctx.Add("MOV.F {}.w,{};"
|
||||||
"TXB.F.LODCLAMP{} {},{},{},{},{}{};",
|
"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);
|
offset_vec);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -309,25 +316,23 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::
|
||||||
ctx.Add("MOV.F {}.z,{};"
|
ctx.Add("MOV.F {}.z,{};"
|
||||||
"MOV.F {}.w,{}.x;"
|
"MOV.F {}.w,{}.x;"
|
||||||
"TXB.F{} {},{},{},{}{};",
|
"TXB.F{} {},{},{},{}{};",
|
||||||
coord_vec, dref, coord_vec, bias_lc, sparse_mod, ret, coord_vec, texture,
|
coord_vec, dref_val, coord_vec, bias_lc_vec, sparse_mod, ret, coord_vec,
|
||||||
type, offset_vec);
|
texture, type, offset_vec);
|
||||||
break;
|
break;
|
||||||
case TextureType::ColorArray2D:
|
case TextureType::ColorArray2D:
|
||||||
case TextureType::ColorCube:
|
case TextureType::ColorCube:
|
||||||
ctx.Add("MOV.F {}.w,{};"
|
ctx.Add("MOV.F {}.w,{};"
|
||||||
"TXB.F{} {},{},{},{},{}{};",
|
"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);
|
offset_vec);
|
||||||
break;
|
break;
|
||||||
case TextureType::ColorArrayCube: {
|
case TextureType::ColorArrayCube:
|
||||||
const ScopedRegister pair{ctx.reg_alloc};
|
|
||||||
ctx.Add("MOV.F {}.x,{};"
|
ctx.Add("MOV.F {}.x,{};"
|
||||||
"MOV.F {}.y,{}.x;"
|
"MOV.F {}.y,{}.x;"
|
||||||
"TXB.F{} {},{},{},{},{}{};",
|
"TXB.F{} {},{},{},{},{}{};",
|
||||||
pair.reg, dref, pair.reg, bias_lc, sparse_mod, ret, coord_vec, pair.reg,
|
staging.reg, dref_val, staging.reg, bias_lc_vec, sparse_mod, ret, coord_vec,
|
||||||
texture, type, offset_vec);
|
staging.reg, texture, type, offset_vec);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
throw NotImplementedException("Invalid type {}", info.type.Value());
|
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'};
|
const char dref_swizzle{w_swizzle ? 'w' : 'z'};
|
||||||
ctx.Add("MOV.F {}.{},{};"
|
ctx.Add("MOV.F {}.{},{};"
|
||||||
"TEX.F.LODCLAMP{} {},{},{},{},{}{};",
|
"TEX.F.LODCLAMP{} {},{},{},{},{}{};",
|
||||||
coord_vec, dref_swizzle, dref, sparse_mod, ret, coord_vec, bias_lc, texture,
|
coord_vec, dref_swizzle, dref_val, sparse_mod, ret, coord_vec, bias_lc_vec,
|
||||||
type, offset_vec);
|
texture, type, offset_vec);
|
||||||
} else {
|
} else {
|
||||||
const ScopedRegister pair{ctx.reg_alloc};
|
|
||||||
ctx.Add("MOV.F {}.x,{};"
|
ctx.Add("MOV.F {}.x,{};"
|
||||||
"MOV.F {}.y,{};"
|
"MOV.F {}.y,{};"
|
||||||
"TEX.F.LODCLAMP{} {},{},{},{},{}{};",
|
"TEX.F.LODCLAMP{} {},{},{},{},{}{};",
|
||||||
pair.reg, dref, pair.reg, bias_lc, sparse_mod, ret, coord_vec, pair.reg,
|
staging.reg, dref_val, staging.reg, bias_lc_vec, sparse_mod, ret, coord_vec,
|
||||||
texture, type, offset_vec);
|
staging.reg, texture, type, offset_vec);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (info.type != TextureType::ColorArrayCube) {
|
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'};
|
const char dref_swizzle{w_swizzle ? 'w' : 'z'};
|
||||||
ctx.Add("MOV.F {}.{},{};"
|
ctx.Add("MOV.F {}.{},{};"
|
||||||
"TEX.F{} {},{},{},{}{};",
|
"TEX.F{} {},{},{},{}{};",
|
||||||
coord_vec, dref_swizzle, dref, sparse_mod, ret, coord_vec, texture, type,
|
coord_vec, dref_swizzle, dref_val, sparse_mod, ret, coord_vec, texture,
|
||||||
offset_vec);
|
type, offset_vec);
|
||||||
} else {
|
} else {
|
||||||
const ScopedRegister pair{ctx.reg_alloc};
|
ctx.Add("TEX.F{} {},{},{},{},{}{};", sparse_mod, ret, coord_vec, dref_val, texture,
|
||||||
ctx.Add("TEX.F{} {},{},{},{},{}{};", sparse_mod, ret, coord_vec, dref, texture,
|
|
||||||
type, offset_vec);
|
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,
|
void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
||||||
const IR::Value& coord, ScalarF32 dref, ScalarF32 lod,
|
const IR::Value& coord, const IR::Value& dref,
|
||||||
const IR::Value& offset) {
|
const IR::Value& lod, const IR::Value& offset) {
|
||||||
|
// Allocate early to avoid aliases
|
||||||
const auto info{inst.Flags<IR::TextureInstInfo>()};
|
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 auto sparse_inst{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSparseFromOp)};
|
||||||
const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
|
const std::string_view sparse_mod{sparse_inst ? ".SPARSE" : ""};
|
||||||
const std::string_view type{TextureType(info)};
|
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,{};"
|
ctx.Add("MOV.F {}.z,{};"
|
||||||
"MOV.F {}.w,{};"
|
"MOV.F {}.w,{};"
|
||||||
"TXL.F{} {},{},{},{}{};",
|
"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);
|
offset_vec);
|
||||||
break;
|
break;
|
||||||
case TextureType::ColorArray2D:
|
case TextureType::ColorArray2D:
|
||||||
case TextureType::ColorCube:
|
case TextureType::ColorCube:
|
||||||
ctx.Add("MOV.F {}.w,{};"
|
ctx.Add("MOV.F {}.w,{};"
|
||||||
"TXL.F{} {},{},{},{},{}{};",
|
"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;
|
break;
|
||||||
case TextureType::ColorArrayCube: {
|
case TextureType::ColorArrayCube:
|
||||||
const ScopedRegister pair{ctx.reg_alloc};
|
|
||||||
ctx.Add("MOV.F {}.x,{};"
|
ctx.Add("MOV.F {}.x,{};"
|
||||||
"MOV.F {}.y,{};"
|
"MOV.F {}.y,{};"
|
||||||
"TXL.F{} {},{},{},{},{}{};",
|
"TXL.F{} {},{},{},{},{}{};",
|
||||||
pair.reg, dref, pair.reg, lod, sparse_mod, ret, coord_vec, pair.reg, texture, type,
|
staging.reg, dref_val, staging.reg, lod_val, sparse_mod, ret, coord_vec,
|
||||||
offset_vec);
|
staging.reg, texture, type, offset_vec);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
throw NotImplementedException("Invalid type {}", info.type.Value());
|
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,
|
void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
||||||
const IR::Value& coord, ScalarF32 lod, const IR::Value& offset);
|
const IR::Value& coord, ScalarF32 lod, const IR::Value& offset);
|
||||||
void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
||||||
const IR::Value& coord, ScalarF32 dref, Register bias_lc,
|
const IR::Value& coord, const IR::Value& dref,
|
||||||
const IR::Value& offset);
|
const IR::Value& bias_lc, const IR::Value& offset);
|
||||||
void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
||||||
const IR::Value& coord, ScalarF32 dref, ScalarF32 lod,
|
const IR::Value& coord, const IR::Value& dref,
|
||||||
const IR::Value& offset);
|
const IR::Value& lod, const IR::Value& offset);
|
||||||
void EmitImageGather(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
void EmitImageGather(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
||||||
const IR::Value& coord, const IR::Value& offset, const IR::Value& offset2);
|
const IR::Value& coord, const IR::Value& offset, const IR::Value& offset2);
|
||||||
void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
||||||
|
|
Reference in New Issue