shader_recompiler: fix emulation of 3D textureGrad
This commit is contained in:
parent
5ce41fa213
commit
9245b426e3
|
@ -558,7 +558,7 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index,
|
||||||
if (multi_component) {
|
if (multi_component) {
|
||||||
if (info.num_derivates >= 3) {
|
if (info.num_derivates >= 3) {
|
||||||
const auto offset_vec{ctx.var_alloc.Consume(offset)};
|
const auto offset_vec{ctx.var_alloc.Consume(offset)};
|
||||||
ctx.Add("{}=textureGrad({},{},vec3({}.xz, {}.x),vec3({}.yz, {}.y));", texel, texture,
|
ctx.Add("{}=textureGrad({},{},vec3({}.xz, {}.x),vec3({}.yw, {}.y));", texel, texture,
|
||||||
coords, derivatives_vec, offset_vec, derivatives_vec, offset_vec);
|
coords, derivatives_vec, offset_vec, derivatives_vec, offset_vec);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,34 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivates_1, Id derivates_2,
|
||||||
|
Id offset, Id lod_clamp) {
|
||||||
|
if (!Sirit::ValidId(derivates_1) || !Sirit::ValidId(derivates_2)) {
|
||||||
|
throw LogicError("Derivates must be present");
|
||||||
|
}
|
||||||
|
boost::container::static_vector<Id, 3> deriv_1_accum{
|
||||||
|
ctx.OpCompositeExtract(ctx.F32[1], derivates_1, 0),
|
||||||
|
ctx.OpCompositeExtract(ctx.F32[1], derivates_1, 2),
|
||||||
|
ctx.OpCompositeExtract(ctx.F32[1], derivates_2, 0),
|
||||||
|
};
|
||||||
|
boost::container::static_vector<Id, 3> deriv_2_accum{
|
||||||
|
ctx.OpCompositeExtract(ctx.F32[1], derivates_1, 1),
|
||||||
|
ctx.OpCompositeExtract(ctx.F32[1], derivates_1, 3),
|
||||||
|
ctx.OpCompositeExtract(ctx.F32[1], derivates_2, 1),
|
||||||
|
};
|
||||||
|
const Id derivates_id1{ctx.OpCompositeConstruct(
|
||||||
|
ctx.F32[3], std::span{deriv_1_accum.data(), deriv_1_accum.size()})};
|
||||||
|
const Id derivates_id2{ctx.OpCompositeConstruct(
|
||||||
|
ctx.F32[3], std::span{deriv_2_accum.data(), deriv_2_accum.size()})};
|
||||||
|
Add(spv::ImageOperandsMask::Grad, derivates_id1, derivates_id2);
|
||||||
|
if (Sirit::ValidId(offset)) {
|
||||||
|
Add(spv::ImageOperandsMask::Offset, offset);
|
||||||
|
}
|
||||||
|
if (has_lod_clamp) {
|
||||||
|
Add(spv::ImageOperandsMask::MinLod, lod_clamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::span<const Id> Span() const noexcept {
|
std::span<const Id> Span() const noexcept {
|
||||||
return std::span{operands.data(), operands.size()};
|
return std::span{operands.data(), operands.size()};
|
||||||
}
|
}
|
||||||
|
@ -524,8 +552,11 @@ Id EmitImageQueryLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, I
|
||||||
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
Id EmitImageGradient(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
|
||||||
Id derivates, Id offset, Id lod_clamp) {
|
Id derivates, Id offset, Id lod_clamp) {
|
||||||
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
const auto info{inst->Flags<IR::TextureInstInfo>()};
|
||||||
const ImageOperands operands(ctx, info.has_lod_clamp != 0, derivates, info.num_derivates,
|
const auto operands =
|
||||||
offset, lod_clamp);
|
info.num_derivates == 3
|
||||||
|
? ImageOperands(ctx, info.has_lod_clamp != 0, derivates, offset, {}, lod_clamp)
|
||||||
|
: ImageOperands(ctx, info.has_lod_clamp != 0, derivates, info.num_derivates, offset,
|
||||||
|
lod_clamp);
|
||||||
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
return Emit(&EmitContext::OpImageSparseSampleExplicitLod,
|
||||||
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
|
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4],
|
||||||
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
|
Texture(ctx, info, index), coords, operands.Mask(), operands.Span());
|
||||||
|
|
Reference in New Issue