shader_recompiler: Improve shader exports accuracy (part 1) (#3447)

* video_core: support for RT layer outputs

- support for RT layer outputs
- refactor for handling of export attributes
- move output->attribute mapping to a separate header

* export: Rework render target exports

- Centralize all code related to MRT exports into a single function to make it easier to follow
- Apply swizzle to output RGBA colors instead of the render target channel.
  This fixes swizzles on formats with < 4 channels

For example with render target format R8_UNORM and COMP_SWAP ALT_REV the previous code would output

frag_color.a = color.r;

instead of

frag_color.r = color.a;

which would result in incorrect output in some cases

* vk_pipeline_cache: Apply swizzle to write masks

---------

Co-authored-by: polyproxy <47796739+polybiusproxy@users.noreply.github.com>
This commit is contained in:
TheTurtle
2025-08-24 00:39:59 +03:00
committed by GitHub
parent d42f4fcc4f
commit 6dd2b3090c
17 changed files with 289 additions and 275 deletions

View File

@@ -52,7 +52,7 @@ struct ExportRuntimeInfo {
auto operator<=>(const ExportRuntimeInfo&) const noexcept = default;
};
enum class VsOutput : u8 {
enum class Output : u8 {
None,
PointSprite,
EdgeFlag,
@@ -77,11 +77,11 @@ enum class VsOutput : u8 {
ClipDist6,
ClipDist7,
};
using VsOutputMap = std::array<VsOutput, 4>;
using OutputMap = std::array<Output, 4>;
struct VertexRuntimeInfo {
u32 num_outputs;
std::array<VsOutputMap, 3> outputs;
std::array<OutputMap, 3> outputs;
bool emulate_depth_negative_one_to_one{};
bool clip_disable{};
u32 step_rate_0;
@@ -145,6 +145,8 @@ struct HullRuntimeInfo {
static constexpr auto GsMaxOutputStreams = 4u;
using GsOutputPrimTypes = std::array<AmdGpu::GsOutputPrimitiveType, GsMaxOutputStreams>;
struct GeometryRuntimeInfo {
u32 num_outputs;
std::array<OutputMap, 3> outputs;
u32 num_invocations{};
u32 output_vertices{};
u32 in_vertex_data_size{};
@@ -179,7 +181,7 @@ struct PsColorBuffer {
u32 pad : 20;
AmdGpu::CompMapping swizzle;
auto operator<=>(const PsColorBuffer&) const noexcept = default;
bool operator==(const PsColorBuffer& other) const noexcept = default;
};
struct FragmentRuntimeInfo {
@@ -189,11 +191,11 @@ struct FragmentRuntimeInfo {
bool is_flat;
u8 default_value;
[[nodiscard]] bool IsDefault() const {
bool IsDefault() const {
return is_default && !is_flat;
}
auto operator<=>(const PsInput&) const noexcept = default;
bool operator==(const PsInput&) const noexcept = default;
};
AmdGpu::Liverpool::PsInput en_flags;
AmdGpu::Liverpool::PsInput addr_flags;