Implement SnormNz conversion (#2841)

* +

* +

* Unpack Snorm 2x16

* +

* SintToSnormNz

* all is broken ig....

* review changes

* my stupid ass messed all while trying to resolve the conflicts..

* +

* +

* fix rebase

* clang-format fix (1)

* clang-format fix (2)

---------

Co-authored-by: squidbus <175574877+squidbus@users.noreply.github.com>
This commit is contained in:
Mahmoud Adel 2025-05-01 12:12:15 +03:00 committed by GitHub
parent 4202d9d621
commit b0e4e87ff3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 50 additions and 6 deletions

0
CMakeLists.txt Executable file → Normal file
View file

View file

@ -206,7 +206,8 @@ static void LowerBufferFormatInst(IR::Block& block, IR::Inst& inst, Info& info)
.swizzle = is_inst_typed .swizzle = is_inst_typed
? AmdGpu::RemapSwizzle(flags.inst_data_fmt.Value(), AmdGpu::IdentityMapping) ? AmdGpu::RemapSwizzle(flags.inst_data_fmt.Value(), AmdGpu::IdentityMapping)
: buffer.DstSelect(), : buffer.DstSelect(),
.num_conversion = is_inst_typed ? AmdGpu::MapNumberConversion(flags.inst_num_fmt.Value()) .num_conversion = is_inst_typed ? AmdGpu::MapNumberConversion(flags.inst_num_fmt.Value(),
flags.inst_data_fmt.Value())
: buffer.GetNumberConversion(), : buffer.GetNumberConversion(),
.num_components = AmdGpu::NumComponents(data_format), .num_components = AmdGpu::NumComponents(data_format),
}; };

View file

@ -34,6 +34,18 @@ inline F32 ApplyReadNumberConversion(IREmitter& ir, const F32& value,
case AmdGpu::NumberConversion::UnormToUbnorm: case AmdGpu::NumberConversion::UnormToUbnorm:
// Convert 0...1 to -1...1 // Convert 0...1 to -1...1
return ir.FPSub(ir.FPMul(value, ir.Imm32(2.f)), ir.Imm32(1.f)); return ir.FPSub(ir.FPMul(value, ir.Imm32(2.f)), ir.Imm32(1.f));
case AmdGpu::NumberConversion::Sint8ToSnormNz: {
const IR::U32 additon = ir.IAdd(ir.IMul(ir.BitCast<U32>(value), ir.Imm32(2)), ir.Imm32(1));
const IR::F32 left = ir.ConvertSToF(32, 32, additon);
const IR::F32 max = ir.Imm32(float(std::numeric_limits<u8>::max()));
return ir.FPDiv(left, max);
}
case AmdGpu::NumberConversion::Sint16ToSnormNz: {
const IR::U32 additon = ir.IAdd(ir.IMul(ir.BitCast<U32>(value), ir.Imm32(2)), ir.Imm32(1));
const IR::F32 left = ir.ConvertSToF(32, 32, additon);
const IR::F32 max = ir.Imm32(float(std::numeric_limits<u16>::max()));
return ir.FPDiv(left, max);
}
default: default:
UNREACHABLE(); UNREACHABLE();
} }
@ -66,6 +78,20 @@ inline F32 ApplyWriteNumberConversion(IREmitter& ir, const F32& value,
case AmdGpu::NumberConversion::UnormToUbnorm: case AmdGpu::NumberConversion::UnormToUbnorm:
// Convert -1...1 to 0...1 // Convert -1...1 to 0...1
return ir.FPDiv(ir.FPAdd(value, ir.Imm32(1.f)), ir.Imm32(2.f)); return ir.FPDiv(ir.FPAdd(value, ir.Imm32(1.f)), ir.Imm32(2.f));
case AmdGpu::NumberConversion::Sint8ToSnormNz: {
const IR::F32 max = ir.Imm32(float(std::numeric_limits<u8>::max()));
const IR::F32 mul = ir.FPMul(ir.FPClamp(value, ir.Imm32(-1.f), ir.Imm32(1.f)), max);
const IR::F32 left = ir.FPSub(mul, ir.Imm32(1.f));
const IR::U32 raw = ir.ConvertFToS(32, ir.FPDiv(left, ir.Imm32(2.f)));
return ir.BitCast<F32>(raw);
}
case AmdGpu::NumberConversion::Sint16ToSnormNz: {
const IR::F32 max = ir.Imm32(float(std::numeric_limits<u16>::max()));
const IR::F32 mul = ir.FPMul(ir.FPClamp(value, ir.Imm32(-1.f), ir.Imm32(1.f)), max);
const IR::F32 left = ir.FPSub(mul, ir.Imm32(1.f));
const IR::U32 raw = ir.ConvertFToS(32, ir.FPDiv(left, ir.Imm32(2.f)));
return ir.BitCast<F32>(raw);
}
default: default:
UNREACHABLE(); UNREACHABLE();
} }

View file

@ -928,7 +928,7 @@ struct Liverpool {
} }
[[nodiscard]] NumberConversion GetNumberConversion() const { [[nodiscard]] NumberConversion GetNumberConversion() const {
return MapNumberConversion(GetFixedNumberFormat()); return MapNumberConversion(GetFixedNumberFormat(), info.format);
} }
[[nodiscard]] CompMapping Swizzle() const { [[nodiscard]] CompMapping Swizzle() const {

View file

@ -68,7 +68,7 @@ struct Buffer {
} }
NumberConversion GetNumberConversion() const noexcept { NumberConversion GetNumberConversion() const noexcept {
return MapNumberConversion(NumberFormat(num_format)); return MapNumberConversion(NumberFormat(num_format), DataFormat(data_format));
} }
u32 GetStride() const noexcept { u32 GetStride() const noexcept {
@ -292,7 +292,7 @@ struct Image {
} }
NumberConversion GetNumberConversion() const noexcept { NumberConversion GetNumberConversion() const noexcept {
return MapNumberConversion(NumberFormat(num_format)); return MapNumberConversion(NumberFormat(num_format), DataFormat(data_format));
} }
TilingMode GetTilingMode() const { TilingMode GetTilingMode() const {

View file

@ -197,6 +197,8 @@ enum class NumberConversion : u32 {
UintToUscaled = 1, UintToUscaled = 1,
SintToSscaled = 2, SintToSscaled = 2,
UnormToUbnorm = 3, UnormToUbnorm = 3,
Sint8ToSnormNz = 5,
Sint16ToSnormNz = 6,
}; };
struct CompMapping { struct CompMapping {
@ -287,6 +289,7 @@ inline NumberFormat RemapNumberFormat(const NumberFormat format, const DataForma
case NumberFormat::Uscaled: case NumberFormat::Uscaled:
return NumberFormat::Uint; return NumberFormat::Uint;
case NumberFormat::Sscaled: case NumberFormat::Sscaled:
case NumberFormat::SnormNz:
return NumberFormat::Sint; return NumberFormat::Sint;
case NumberFormat::Ubnorm: case NumberFormat::Ubnorm:
return NumberFormat::Unorm; return NumberFormat::Unorm;
@ -336,14 +339,28 @@ inline CompMapping RemapSwizzle(const DataFormat format, const CompMapping swizz
} }
} }
inline NumberConversion MapNumberConversion(const NumberFormat format) { inline NumberConversion MapNumberConversion(const NumberFormat num_fmt, const DataFormat data_fmt) {
switch (format) { switch (num_fmt) {
case NumberFormat::Uscaled: case NumberFormat::Uscaled:
return NumberConversion::UintToUscaled; return NumberConversion::UintToUscaled;
case NumberFormat::Sscaled: case NumberFormat::Sscaled:
return NumberConversion::SintToSscaled; return NumberConversion::SintToSscaled;
case NumberFormat::Ubnorm: case NumberFormat::Ubnorm:
return NumberConversion::UnormToUbnorm; return NumberConversion::UnormToUbnorm;
case NumberFormat::SnormNz: {
switch (data_fmt) {
case DataFormat::Format8:
case DataFormat::Format8_8:
case DataFormat::Format8_8_8_8:
return NumberConversion::Sint8ToSnormNz;
case DataFormat::Format16:
case DataFormat::Format16_16:
case DataFormat::Format16_16_16_16:
return NumberConversion::Sint16ToSnormNz;
default:
UNREACHABLE_MSG("data_fmt = {}", u32(data_fmt));
}
}
default: default:
return NumberConversion::None; return NumberConversion::None;
} }