mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-26 12:56:54 +01:00
shader: type pixel outputs of UINT and SINT render targets as integer vectors
Co-authored-by: Ali Almohaya <AliAlmohaya@gmail.com> Co-authored-by: Mac <me@itsmemac.com> Co-authored-by: Senaxx <michelbeld@gmail.com>
This commit is contained in:
@@ -19808,6 +19808,40 @@ public:
|
||||
}
|
||||
Require(name, "packed rounding program distinction", half_up_program != truncate_program,
|
||||
"half-up and truncate exports shared one shader specialization");
|
||||
// UINT and SINT targets give their exports integer outputs.
|
||||
registers.Reset();
|
||||
registers.SetViewportTransformControl(0x300);
|
||||
registers.SetRenderTargetMask(0xffu);
|
||||
registers.SetShaderMask(0xffu);
|
||||
shaders.SetPsShaderBase(pixel_address);
|
||||
for (const auto [slot, type] : {std::pair{0u, Prospero::ChannelType::kUInt},
|
||||
std::pair{1u, Prospero::ChannelType::kSInt}}) {
|
||||
registers.SetTargetOutputMode(slot, 9);
|
||||
registers.SetColorBase(slot, {.addr = depth_address + 0x10000 * (slot + 1)});
|
||||
registers.SetColorInfo(slot, {.format = Prospero::ChannelLayout::k32, .channel_type = type,
|
||||
.channel_order = Prospero::ChannelOrder::kStandard});
|
||||
registers.SetColorAttrib2(slot, {.height = extent - 1, .width = extent - 1});
|
||||
registers.SetColorAttrib3(slot, {.tile_mode = Prospero::TileMode::kLinear, .dimension = 1});
|
||||
}
|
||||
native_programs();
|
||||
Require(name, "integer target outputs",
|
||||
pixel.target_uint_mask == 1u && pixel.target_sint_mask == 2u,
|
||||
"UINT and SINT targets did not select integer export outputs");
|
||||
// MRT1 is the second blend source of a dual-source float target 0, not integer target 1.
|
||||
HW::BlendControl dual_blend{};
|
||||
dual_blend.enable = true;
|
||||
dual_blend.color_srcblend = static_cast<uint8_t>(Prospero::BlendFactor::kSrc1Color);
|
||||
registers.SetBlendControl(0, dual_blend);
|
||||
for (const auto [slot, type] : {std::pair{0u, Prospero::ChannelType::kFloat},
|
||||
std::pair{1u, Prospero::ChannelType::kUInt}}) {
|
||||
registers.SetColorInfo(slot, {.format = Prospero::ChannelLayout::k32, .channel_type = type,
|
||||
.channel_order = Prospero::ChannelOrder::kStandard});
|
||||
native_programs();
|
||||
Require(name, "dual-source float outputs",
|
||||
pixel.dual_source_blending && pixel.target_uint_mask == 0u &&
|
||||
pixel.target_sint_mask == 0u,
|
||||
"the second blend source kept the integer type of render target 1");
|
||||
}
|
||||
DestroyBuffer(&packed_output);
|
||||
m_device.destroySampler(packed_sampler);
|
||||
DestroyBuffer(&stencil_readback);
|
||||
|
||||
@@ -13748,6 +13748,7 @@ void TestNewShaderRecompilerExpPixelOutputs() {
|
||||
|
||||
ShaderPixelInputInfo uint16_info;
|
||||
uint16_info.target_output_mode[0] = 7;
|
||||
uint16_info.target_uint_mask = 1;
|
||||
options.input_info.pixel = &uint16_info;
|
||||
auto uint16_result = RecompileForTest(shader, options);
|
||||
const auto uint16_source = DisassembleSpirvBinary(uint16_result.spirv);
|
||||
@@ -13762,6 +13763,18 @@ void TestNewShaderRecompilerExpPixelOutputs() {
|
||||
"compressed UINT16 MRT export was incorrectly decoded as FP16");
|
||||
CheckSpirvBinaryValidates(uint16_result.spirv);
|
||||
|
||||
ShaderPixelInputInfo sint16_info;
|
||||
sint16_info.target_output_mode[0] = 8;
|
||||
sint16_info.target_sint_mask = 1;
|
||||
options.input_info.pixel = &sint16_info;
|
||||
auto sint16_result = RecompileForTest(shader, options);
|
||||
const auto sint16_source = DisassembleSpirvBinary(sint16_result.spirv);
|
||||
Check(sint16_source.find("OpVariable %_ptr_Output_v4int Output") != std::string::npos &&
|
||||
CountSourceOccurrences(sint16_source, "OpBitFieldSExtract") == 4u &&
|
||||
!SpirvContainsExtInst(sint16_result.spirv, 62),
|
||||
"compressed SINT16 MRT export did not sign-extend into a signed output");
|
||||
CheckSpirvBinaryValidates(sint16_result.spirv);
|
||||
|
||||
ShaderPixelInputInfo unorm16_info;
|
||||
unorm16_info.target_output_mode[0] = 5;
|
||||
options.input_info.pixel = &unorm16_info;
|
||||
@@ -13789,6 +13802,7 @@ void TestNewShaderRecompilerExpPixelOutputs() {
|
||||
|
||||
ShaderPixelInputInfo uint_info;
|
||||
uint_info.target_output_mode[0] = 7;
|
||||
uint_info.target_uint_mask = 1;
|
||||
options.input_info.pixel = &uint_info;
|
||||
auto partial_uint_result =
|
||||
RecompileForTest(partial_shader, options);
|
||||
@@ -13815,6 +13829,15 @@ void TestNewShaderRecompilerExpPixelOutputs() {
|
||||
"compressed UINT16 BA-only export did not read and unpack VSRC1");
|
||||
CheckSpirvBinaryValidates(compressed_ba_result.spirv);
|
||||
|
||||
// 32-bit exports keep their raw bits in a UINT target's integer output.
|
||||
uint_info.target_output_mode[0] = 9;
|
||||
auto raw_uint_result = RecompileForTest(partial_shader, options);
|
||||
const auto raw_uint_source = DisassembleSpirvBinary(raw_uint_result.spirv);
|
||||
Check(raw_uint_source.find("OpVariable %_ptr_Output_v4uint Output") != std::string::npos &&
|
||||
raw_uint_source.find("OpBitcast %v4float") == std::string::npos,
|
||||
"32-bit MRT export to a UINT target did not use an unsigned integer output");
|
||||
CheckSpirvBinaryValidates(raw_uint_result.spirv);
|
||||
|
||||
unorm16_info.target_output_mode[0] = 5;
|
||||
options.input_info.pixel = &unorm16_info;
|
||||
auto unorm16_ba_result =
|
||||
|
||||
Reference in New Issue
Block a user