shader: Address feedback
This commit is contained in:
parent
cb6fc03e55
commit
4d0d29fc20
|
@ -72,20 +72,19 @@ public:
|
||||||
explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivates, u32 num_derivates,
|
explicit ImageOperands(EmitContext& ctx, bool has_lod_clamp, Id derivates, u32 num_derivates,
|
||||||
Id offset, Id lod_clamp) {
|
Id offset, Id lod_clamp) {
|
||||||
if (Sirit::ValidId(derivates)) {
|
if (Sirit::ValidId(derivates)) {
|
||||||
|
throw LogicError("Derivates must be present");
|
||||||
|
}
|
||||||
boost::container::static_vector<Id, 3> deriv_x_accum;
|
boost::container::static_vector<Id, 3> deriv_x_accum;
|
||||||
boost::container::static_vector<Id, 3> deriv_y_accum;
|
boost::container::static_vector<Id, 3> deriv_y_accum;
|
||||||
for (size_t i = 0; i < num_derivates; i++) {
|
for (size_t i = 0; i < num_derivates; i++) {
|
||||||
deriv_x_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivates, i * 2));
|
deriv_x_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivates, i * 2));
|
||||||
deriv_y_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivates, i * 2 + 1));
|
deriv_y_accum.push_back(ctx.OpCompositeExtract(ctx.F32[1], derivates, i * 2 + 1));
|
||||||
}
|
}
|
||||||
Id derivates_X = ctx.OpCompositeConstruct(
|
const Id derivates_X{ctx.OpCompositeConstruct(
|
||||||
ctx.F32[num_derivates], std::span{deriv_x_accum.data(), deriv_x_accum.size()});
|
ctx.F32[num_derivates], std::span{deriv_x_accum.data(), deriv_x_accum.size()})};
|
||||||
Id derivates_Y = ctx.OpCompositeConstruct(
|
const Id derivates_Y{ctx.OpCompositeConstruct(
|
||||||
ctx.F32[num_derivates], std::span{deriv_y_accum.data(), deriv_y_accum.size()});
|
ctx.F32[num_derivates], std::span{deriv_y_accum.data(), deriv_y_accum.size()})};
|
||||||
Add(spv::ImageOperandsMask::Grad, derivates_X, derivates_Y);
|
Add(spv::ImageOperandsMask::Grad, derivates_X, derivates_Y);
|
||||||
} else {
|
|
||||||
throw LogicError("Derivates must be present");
|
|
||||||
}
|
|
||||||
if (Sirit::ValidId(offset)) {
|
if (Sirit::ValidId(offset)) {
|
||||||
Add(spv::ImageOperandsMask::Offset, offset);
|
Add(spv::ImageOperandsMask::Offset, offset);
|
||||||
}
|
}
|
||||||
|
@ -100,10 +99,10 @@ public:
|
||||||
operands.push_back(value);
|
operands.push_back(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Add(spv::ImageOperandsMask new_mask, Id value, Id value_2) {
|
void Add(spv::ImageOperandsMask new_mask, Id value_1, Id value_2) {
|
||||||
mask = static_cast<spv::ImageOperandsMask>(static_cast<unsigned>(mask) |
|
mask = static_cast<spv::ImageOperandsMask>(static_cast<unsigned>(mask) |
|
||||||
static_cast<unsigned>(new_mask));
|
static_cast<unsigned>(new_mask));
|
||||||
operands.push_back(value);
|
operands.push_back(value_1);
|
||||||
operands.push_back(value_2);
|
operands.push_back(value_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +344,8 @@ Id EmitImageQueryLod(EmitContext& ctx, IR::Inst*, const IR::Value& index, Id coo
|
||||||
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, offset, lod_clamp);
|
const ImageOperands operands(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], Texture(ctx, index),
|
&EmitContext::OpImageSampleExplicitLod, ctx, inst, ctx.F32[4], Texture(ctx, index),
|
||||||
coords, operands.Mask(), operands.Span());
|
coords, operands.Mask(), operands.Span());
|
||||||
|
|
|
@ -47,7 +47,7 @@ Shader::TextureType GetType(TextureType type, bool dc) {
|
||||||
|
|
||||||
IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg reg, bool has_lod_clamp) {
|
IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg reg, bool has_lod_clamp) {
|
||||||
const IR::U32 value{v.X(reg)};
|
const IR::U32 value{v.X(reg)};
|
||||||
const u32 base = has_lod_clamp ? 12 : 16;
|
const u32 base{has_lod_clamp ? 12U : 16U};
|
||||||
return v.ir.CompositeConstruct(
|
return v.ir.CompositeConstruct(
|
||||||
v.ir.BitFieldExtract(value, v.ir.Imm32(base), v.ir.Imm32(4), true),
|
v.ir.BitFieldExtract(value, v.ir.Imm32(base), v.ir.Imm32(4), true),
|
||||||
v.ir.BitFieldExtract(value, v.ir.Imm32(base + 4), v.ir.Imm32(4), true));
|
v.ir.BitFieldExtract(value, v.ir.Imm32(base + 4), v.ir.Imm32(4), true));
|
||||||
|
@ -74,20 +74,21 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
|
||||||
}
|
}
|
||||||
|
|
||||||
IR::Value coords;
|
IR::Value coords;
|
||||||
u32 num_derivates;
|
u32 num_derivates{};
|
||||||
IR::Reg base_reg = txd.coord_reg;
|
IR::Reg base_reg{txd.coord_reg};
|
||||||
IR::Reg last_reg;
|
IR::Reg last_reg;
|
||||||
IR::Value handle;
|
IR::Value handle;
|
||||||
if (!is_bindless) {
|
if (is_bindless) {
|
||||||
handle = v.ir.Imm32(static_cast<u32>(txd.cbuf_offset.Value() * 4));
|
|
||||||
} else {
|
|
||||||
handle = v.X(base_reg++);
|
handle = v.X(base_reg++);
|
||||||
|
} else {
|
||||||
|
handle = v.ir.Imm32(static_cast<u32>(txd.cbuf_offset.Value() * 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto read_array{[&]() -> IR::F32 {
|
const auto read_array{[&]() -> IR::F32 {
|
||||||
return v.ir.ConvertUToF(32, 16,
|
const IR::U32 base{v.ir.Imm32(0)};
|
||||||
v.ir.BitFieldExtract(v.X(last_reg), v.ir.Imm32(0),
|
const IR::U32 count{v.ir.Imm32(has_lod_clamp ? 12 : 16)};
|
||||||
v.ir.Imm32(has_lod_clamp ? 12 : 16)));
|
const IR::U32 array_index{v.ir.BitFieldExtract(v.X(last_reg), base, count)};
|
||||||
|
return v.ir.ConvertUToF(32, 16, array_index);
|
||||||
}};
|
}};
|
||||||
switch (txd.type) {
|
switch (txd.type) {
|
||||||
case TextureType::_1D: {
|
case TextureType::_1D: {
|
||||||
|
@ -141,19 +142,20 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
|
||||||
|
|
||||||
IR::F32 lod_clamp;
|
IR::F32 lod_clamp;
|
||||||
if (has_lod_clamp) {
|
if (has_lod_clamp) {
|
||||||
const IR::F32 conv4_8fixp_f = v.ir.Imm32(Common::BitCast<f32>(0x3b800000U));
|
// Lod Clamp is a Fixed Point 4.8, we need to transform it to float.
|
||||||
const IR::F32 tmp = v.ir.ConvertUToF(
|
// to convert a fixed point, float(value) / float(1 << fixed_point)
|
||||||
32, 16, v.ir.BitFieldExtract(v.X(last_reg), v.ir.Imm32(20), v.ir.Imm32(12)));
|
// in this case the fixed_point is 8.
|
||||||
lod_clamp = v.ir.FPMul(tmp, conv4_8fixp_f);
|
const IR::F32 conv4_8fixp_f{v.ir.Imm32(static_cast<f32>(1U << 8))};
|
||||||
|
const IR::F32 fixp_lc{v.ir.ConvertUToF(
|
||||||
|
32, 16, v.ir.BitFieldExtract(v.X(last_reg), v.ir.Imm32(20), v.ir.Imm32(12)))};
|
||||||
|
lod_clamp = v.ir.FPMul(fixp_lc, conv4_8fixp_f);
|
||||||
}
|
}
|
||||||
|
|
||||||
IR::TextureInstInfo info{};
|
IR::TextureInstInfo info{};
|
||||||
info.type.Assign(GetType(txd.type, false));
|
info.type.Assign(GetType(txd.type, false));
|
||||||
info.num_derivates.Assign(num_derivates);
|
info.num_derivates.Assign(num_derivates);
|
||||||
info.has_lod_clamp.Assign(has_lod_clamp ? 1 : 0);
|
info.has_lod_clamp.Assign(has_lod_clamp ? 1 : 0);
|
||||||
const IR::Value sample{[&]() -> IR::Value {
|
const IR::Value sample{v.ir.ImageGradient(handle, coords, derivates, offset, lod_clamp, info)};
|
||||||
return v.ir.ImageGradient(handle, coords, derivates, offset, lod_clamp, info);
|
|
||||||
}()};
|
|
||||||
|
|
||||||
IR::Reg dest_reg{txd.dest_reg};
|
IR::Reg dest_reg{txd.dest_reg};
|
||||||
for (size_t element = 0; element < 4; ++element) {
|
for (size_t element = 0; element < 4; ++element) {
|
||||||
|
|
|
@ -117,10 +117,10 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
|
||||||
IR::Value offset;
|
IR::Value offset;
|
||||||
IR::U32 lod;
|
IR::U32 lod;
|
||||||
IR::U32 multisample;
|
IR::U32 multisample;
|
||||||
if (!is_bindless) {
|
if (is_bindless) {
|
||||||
handle = v.ir.Imm32(static_cast<u32>(tld.cbuf_offset.Value() * 4));
|
|
||||||
} else {
|
|
||||||
handle = v.X(meta_reg++);
|
handle = v.X(meta_reg++);
|
||||||
|
} else {
|
||||||
|
handle = v.ir.Imm32(static_cast<u32>(tld.cbuf_offset.Value() * 4));
|
||||||
}
|
}
|
||||||
if (tld.lod != 0) {
|
if (tld.lod != 0) {
|
||||||
lod = v.X(meta_reg++);
|
lod = v.X(meta_reg++);
|
||||||
|
@ -138,9 +138,7 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
|
||||||
}
|
}
|
||||||
IR::TextureInstInfo info{};
|
IR::TextureInstInfo info{};
|
||||||
info.type.Assign(GetType(tld.type, false));
|
info.type.Assign(GetType(tld.type, false));
|
||||||
const IR::Value sample{[&]() -> IR::Value {
|
const IR::Value sample{v.ir.ImageFetch(handle, coords, offset, lod, multisample, info)};
|
||||||
return v.ir.ImageFetch(handle, coords, offset, lod, multisample, info);
|
|
||||||
}()};
|
|
||||||
|
|
||||||
IR::Reg dest_reg{tld.dest_reg};
|
IR::Reg dest_reg{tld.dest_reg};
|
||||||
for (size_t element = 0; element < 4; ++element) {
|
for (size_t element = 0; element < 4; ++element) {
|
||||||
|
|
|
@ -81,39 +81,35 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
|
||||||
BitField<36, 13, u64> cbuf_offset;
|
BitField<36, 13, u64> cbuf_offset;
|
||||||
} const tmml{insn};
|
} const tmml{insn};
|
||||||
|
|
||||||
if ((tmml.mask & 0xC) != 0) {
|
if ((tmml.mask & 0b1100) != 0) {
|
||||||
throw NotImplementedException("TMML BA results are not implmented");
|
throw NotImplementedException("TMML BA results are not implmented");
|
||||||
}
|
}
|
||||||
|
|
||||||
IR::F32 transform_constant = v.ir.Imm32(256.0f);
|
IR::F32 transform_constant{v.ir.Imm32(256.0f)};
|
||||||
|
|
||||||
const IR::Value coords{MakeCoords(v, tmml.coord_reg, tmml.type)};
|
const IR::Value coords{MakeCoords(v, tmml.coord_reg, tmml.type)};
|
||||||
|
|
||||||
IR::U32 handle;
|
IR::U32 handle;
|
||||||
IR::Reg meta_reg{tmml.meta_reg};
|
IR::Reg meta_reg{tmml.meta_reg};
|
||||||
if (!is_bindless) {
|
if (is_bindless) {
|
||||||
handle = v.ir.Imm32(static_cast<u32>(tmml.cbuf_offset.Value() * 4));
|
|
||||||
} else {
|
|
||||||
handle = v.X(meta_reg++);
|
handle = v.X(meta_reg++);
|
||||||
|
} else {
|
||||||
|
handle = v.ir.Imm32(static_cast<u32>(tmml.cbuf_offset.Value() * 4));
|
||||||
}
|
}
|
||||||
IR::TextureInstInfo info{};
|
IR::TextureInstInfo info{};
|
||||||
info.type.Assign(GetType(tmml.type, false));
|
info.type.Assign(GetType(tmml.type, false));
|
||||||
const IR::Value sample{
|
const IR::Value sample{v.ir.ImageQueryLod(handle, coords, info)};
|
||||||
[&]() -> IR::Value { return v.ir.ImageQueryLod(handle, coords, info); }()};
|
|
||||||
|
|
||||||
const IR::FpControl fp_control{
|
|
||||||
.no_contraction{false},
|
|
||||||
.rounding{IR::FpRounding::RP},
|
|
||||||
.fmz_mode{IR::FmzMode::FTZ},
|
|
||||||
};
|
|
||||||
IR::Reg dest_reg{tmml.dest_reg};
|
IR::Reg dest_reg{tmml.dest_reg};
|
||||||
for (size_t element = 0; element < 4; ++element) {
|
for (size_t element = 0; element < 4; ++element) {
|
||||||
if (((tmml.mask >> element) & 1) == 0) {
|
if (((tmml.mask >> element) & 1) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
IR::F32 value = IR::F32{v.ir.CompositeExtract(sample, element)};
|
IR::F32 value{v.ir.CompositeExtract(sample, element)};
|
||||||
v.F(dest_reg,
|
if (element < 2) {
|
||||||
element < 2 ? IR::F32{v.ir.FPMul(value, transform_constant, fp_control)} : value);
|
value = v.ir.FPMul(value, transform_constant);
|
||||||
|
}
|
||||||
|
v.F(dest_reg, value);
|
||||||
++dest_reg;
|
++dest_reg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) {
|
||||||
}
|
}
|
||||||
const auto it = std::ranges::lower_bound(map_ranges, gpu_addr, {}, &MapRange::first);
|
const auto it = std::ranges::lower_bound(map_ranges, gpu_addr, {}, &MapRange::first);
|
||||||
if (it != map_ranges.end()) {
|
if (it != map_ranges.end()) {
|
||||||
// ASSERT(it->first == gpu_addr);
|
ASSERT(it->first == gpu_addr);
|
||||||
map_ranges.erase(it);
|
map_ranges.erase(it);
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE_MSG("Unmapping non-existent GPU address=0x{:x}", gpu_addr);
|
UNREACHABLE_MSG("Unmapping non-existent GPU address=0x{:x}", gpu_addr);
|
||||||
|
|
Reference in New Issue