mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
shader: decode compressed UNORM16 MRT exports
This commit is contained in:
@@ -203,10 +203,12 @@ uint32_t EmitAttribute(ValueEmitContext& ctx, uint32_t attr, uint32_t chan) {
|
|||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MrtUsesUint(const EmitterState& state, const IR::ExportInfo& exp) {
|
uint32_t MrtOutputMode(const EmitterState& state, const IR::ExportInfo& exp) {
|
||||||
return state.stage == ShaderType::Pixel && exp.kind == IR::ExportTargetKind::Mrt &&
|
if (state.stage != ShaderType::Pixel || exp.kind != IR::ExportTargetKind::Mrt ||
|
||||||
exp.index < std::size(state.input_info.pixel->target_output_mode) &&
|
exp.index >= std::size(state.input_info.pixel->target_output_mode)) {
|
||||||
state.input_info.pixel->target_output_mode[exp.index] == 7u;
|
return 0;
|
||||||
|
}
|
||||||
|
return state.input_info.pixel->target_output_mode[exp.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ExportRawComponent(ValueEmitContext& ctx, uint32_t vector, uint32_t component) {
|
uint32_t ExportRawComponent(ValueEmitContext& ctx, uint32_t vector, uint32_t component) {
|
||||||
@@ -220,6 +222,8 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
|
|||||||
bool uint_output) {
|
bool uint_output) {
|
||||||
auto& state = ctx.state;
|
auto& state = ctx.state;
|
||||||
if (exp.compr && !uint_output) {
|
if (exp.compr && !uint_output) {
|
||||||
|
const auto unpack = MrtOutputMode(state, exp) == 5u ? GlslUnpackUnorm2x16
|
||||||
|
: GlslUnpackHalf2x16;
|
||||||
uint32_t f32[4] = {ConstantF32(state, 0), ConstantF32(state, 0), ConstantF32(state, 0),
|
uint32_t f32[4] = {ConstantF32(state, 0), ConstantF32(state, 0), ConstantF32(state, 0),
|
||||||
ConstantF32(state, 0x3f800000u)};
|
ConstantF32(state, 0x3f800000u)};
|
||||||
for (uint32_t pair = 0; pair < 2u; pair++) {
|
for (uint32_t pair = 0; pair < 2u; pair++) {
|
||||||
@@ -229,8 +233,8 @@ uint32_t ExportVector(ValueEmitContext& ctx, uint32_t data, const IR::ExportInfo
|
|||||||
const auto packed = state.builder.AllocateId();
|
const auto packed = state.builder.AllocateId();
|
||||||
const auto unpacked = state.builder.AllocateId();
|
const auto unpacked = state.builder.AllocateId();
|
||||||
state.builder.AddFunction({OpCompositeExtract, TypeU32(state), packed, data, pair});
|
state.builder.AddFunction({OpCompositeExtract, TypeU32(state), packed, data, pair});
|
||||||
state.builder.AddFunction({OpExtInst, TypeF32Vector(state, 2), unpacked,
|
state.builder.AddFunction(
|
||||||
GlslStd450(state), GlslUnpackHalf2x16, packed});
|
{OpExtInst, TypeF32Vector(state, 2), unpacked, GlslStd450(state), unpack, packed});
|
||||||
for (uint32_t lane = 0; lane < 2u; lane++) {
|
for (uint32_t lane = 0; lane < 2u; lane++) {
|
||||||
const auto component = pair * 2u + lane;
|
const auto component = pair * 2u + lane;
|
||||||
if (((exp.en >> component) & 1u) != 0u) {
|
if (((exp.en >> component) & 1u) != 0u) {
|
||||||
@@ -332,7 +336,7 @@ void EmitExport(ValueEmitContext& ctx, const IR::Inst& inst) {
|
|||||||
if (variable == 0) {
|
if (variable == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const bool uint_output = MrtUsesUint(state, exp);
|
const bool uint_output = MrtOutputMode(state, exp) == 7u;
|
||||||
const auto vector_type = uint_output ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4);
|
const auto vector_type = uint_output ? TypeU32Vector(state, 4) : TypeF32Vector(state, 4);
|
||||||
auto value = ExportVector(ctx, data, exp, uint_output);
|
auto value = ExportVector(ctx, data, exp, uint_output);
|
||||||
if (state.stage == ShaderType::Pixel && exp.kind == IR::ExportTargetKind::Mrt &&
|
if (state.stage == ShaderType::Pixel && exp.kind == IR::ExportTargetKind::Mrt &&
|
||||||
|
|||||||
@@ -271,6 +271,7 @@ enum : uint32_t {
|
|||||||
GlslPackSnorm2x16 = 56,
|
GlslPackSnorm2x16 = 56,
|
||||||
GlslPackUnorm2x16 = 57,
|
GlslPackUnorm2x16 = 57,
|
||||||
GlslPackHalf2x16 = 58,
|
GlslPackHalf2x16 = 58,
|
||||||
|
GlslUnpackUnorm2x16 = 61,
|
||||||
GlslUnpackHalf2x16 = 62,
|
GlslUnpackHalf2x16 = 62,
|
||||||
GlslFindILsb = 73,
|
GlslFindILsb = 73,
|
||||||
GlslFindUMsb = 75,
|
GlslFindUMsb = 75,
|
||||||
|
|||||||
@@ -9851,6 +9851,19 @@ void TestNewShaderRecompilerExpPixelOutputs() {
|
|||||||
"compressed UINT16 MRT export was incorrectly decoded as FP16");
|
"compressed UINT16 MRT export was incorrectly decoded as FP16");
|
||||||
CheckSpirvBinaryValidates(uint16_result.spirv);
|
CheckSpirvBinaryValidates(uint16_result.spirv);
|
||||||
|
|
||||||
|
ShaderPixelInputInfo unorm16_info;
|
||||||
|
unorm16_info.target_output_mode[0] = 5;
|
||||||
|
options.input_info.pixel = &unorm16_info;
|
||||||
|
ShaderRecompiler::CompileResult unorm16_result;
|
||||||
|
Check(ShaderRecompiler::TryRecompile(shader, options, unorm16_result, &error),
|
||||||
|
error.c_str());
|
||||||
|
const auto unorm16_source = DisassembleSpirvBinary(unorm16_result.spirv);
|
||||||
|
Check(CountSourceOccurrences(unorm16_source, "UnpackUnorm2x16") == 2u,
|
||||||
|
"compressed UNORM16 MRT export did not unpack two normalized pairs");
|
||||||
|
Check(!SpirvContainsExtInst(unorm16_result.spirv, 62),
|
||||||
|
"compressed UNORM16 MRT export was incorrectly decoded as FP16");
|
||||||
|
CheckSpirvBinaryValidates(unorm16_result.spirv);
|
||||||
|
|
||||||
const uint32_t partial_shader[] = {
|
const uint32_t partial_shader[] = {
|
||||||
EncodeExp0(0x00, 0x7),
|
EncodeExp0(0x00, 0x7),
|
||||||
EncodeExp1(0, 1, 2, 3),
|
EncodeExp1(0, 1, 2, 3),
|
||||||
@@ -9899,6 +9912,17 @@ void TestNewShaderRecompilerExpPixelOutputs() {
|
|||||||
"OpBitFieldUExtract") == 2u,
|
"OpBitFieldUExtract") == 2u,
|
||||||
"compressed UINT16 BA-only export did not read and unpack VSRC1");
|
"compressed UINT16 BA-only export did not read and unpack VSRC1");
|
||||||
CheckSpirvBinaryValidates(compressed_ba_result.spirv);
|
CheckSpirvBinaryValidates(compressed_ba_result.spirv);
|
||||||
|
|
||||||
|
unorm16_info.target_output_mode[0] = 5;
|
||||||
|
options.input_info.pixel = &unorm16_info;
|
||||||
|
ShaderRecompiler::CompileResult unorm16_ba_result;
|
||||||
|
Check(ShaderRecompiler::TryRecompile(compressed_ba_shader, options,
|
||||||
|
unorm16_ba_result, &error),
|
||||||
|
error.c_str());
|
||||||
|
const auto unorm16_ba_source = DisassembleSpirvBinary(unorm16_ba_result.spirv);
|
||||||
|
Check(CountSourceOccurrences(unorm16_ba_source, "UnpackUnorm2x16") == 1u,
|
||||||
|
"compressed UNORM16 BA-only export did not unpack VSRC1");
|
||||||
|
CheckSpirvBinaryValidates(unorm16_ba_result.spirv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRenderTargetReverseExportMapping() {
|
void TestRenderTargetReverseExportMapping() {
|
||||||
|
|||||||
Reference in New Issue
Block a user