mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-02-04 20:48:15 +00:00
recompiler: fixed fragment shader built-in attribute access (#1676)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
* recompiler: fixed fragment shader built-in attribute access * handle en/addr separately * handle other registers as well
This commit is contained in:
parent
e1ecfb8dd1
commit
8eacb88a86
|
@ -53,15 +53,74 @@ void Translator::EmitPrologue() {
|
|||
}
|
||||
break;
|
||||
case Stage::Fragment:
|
||||
// https://github.com/chaotic-cx/mesa-mirror/blob/72326e15/src/amd/vulkan/radv_shader_args.c#L258
|
||||
// The first two VGPRs are used for i/j barycentric coordinates. In the vast majority of
|
||||
// cases it will be only those two, but if shader is using both e.g linear and perspective
|
||||
// inputs it can be more For now assume that this isn't the case.
|
||||
dst_vreg = IR::VectorReg::V2;
|
||||
for (u32 i = 0; i < 4; i++) {
|
||||
ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, i));
|
||||
dst_vreg = IR::VectorReg::V0;
|
||||
if (runtime_info.fs_info.addr_flags.persp_sample_ena) {
|
||||
++dst_vreg; // I
|
||||
++dst_vreg; // J
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.persp_center_ena) {
|
||||
++dst_vreg; // I
|
||||
++dst_vreg; // J
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.persp_centroid_ena) {
|
||||
++dst_vreg; // I
|
||||
++dst_vreg; // J
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.persp_pull_model_ena) {
|
||||
++dst_vreg; // I/W
|
||||
++dst_vreg; // J/W
|
||||
++dst_vreg; // 1/W
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.linear_sample_ena) {
|
||||
++dst_vreg; // I
|
||||
++dst_vreg; // J
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.linear_center_ena) {
|
||||
++dst_vreg; // I
|
||||
++dst_vreg; // J
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.linear_centroid_ena) {
|
||||
++dst_vreg; // I
|
||||
++dst_vreg; // J
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.line_stipple_tex_ena) {
|
||||
++dst_vreg;
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.pos_x_float_ena) {
|
||||
if (runtime_info.fs_info.en_flags.pos_x_float_ena) {
|
||||
ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, 0));
|
||||
} else {
|
||||
ir.SetVectorReg(dst_vreg++, ir.Imm32(0.0f));
|
||||
}
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.pos_y_float_ena) {
|
||||
if (runtime_info.fs_info.en_flags.pos_y_float_ena) {
|
||||
ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, 1));
|
||||
} else {
|
||||
ir.SetVectorReg(dst_vreg++, ir.Imm32(0.0f));
|
||||
}
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.pos_z_float_ena) {
|
||||
if (runtime_info.fs_info.en_flags.pos_z_float_ena) {
|
||||
ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, 2));
|
||||
} else {
|
||||
ir.SetVectorReg(dst_vreg++, ir.Imm32(0.0f));
|
||||
}
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.pos_w_float_ena) {
|
||||
if (runtime_info.fs_info.en_flags.pos_w_float_ena) {
|
||||
ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, 3));
|
||||
} else {
|
||||
ir.SetVectorReg(dst_vreg++, ir.Imm32(0.0f));
|
||||
}
|
||||
}
|
||||
if (runtime_info.fs_info.addr_flags.front_face_ena) {
|
||||
if (runtime_info.fs_info.en_flags.front_face_ena) {
|
||||
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::IsFrontFace));
|
||||
} else {
|
||||
ir.SetVectorReg(dst_vreg++, ir.Imm32(0));
|
||||
}
|
||||
}
|
||||
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::IsFrontFace));
|
||||
break;
|
||||
case Stage::Compute:
|
||||
ir.SetVectorReg(dst_vreg++, ir.GetAttributeU32(IR::Attribute::LocalInvocationId, 0));
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <span>
|
||||
#include <boost/container/static_vector.hpp>
|
||||
#include "common/types.h"
|
||||
#include "video_core/amdgpu/liverpool.h"
|
||||
#include "video_core/amdgpu/types.h"
|
||||
|
||||
namespace Shader {
|
||||
|
@ -105,6 +106,8 @@ struct FragmentRuntimeInfo {
|
|||
|
||||
auto operator<=>(const PsInput&) const noexcept = default;
|
||||
};
|
||||
AmdGpu::Liverpool::PsInput en_flags;
|
||||
AmdGpu::Liverpool::PsInput addr_flags;
|
||||
u32 num_inputs;
|
||||
std::array<PsInput, 32> inputs;
|
||||
struct PsColorBuffer {
|
||||
|
@ -117,6 +120,7 @@ struct FragmentRuntimeInfo {
|
|||
|
||||
bool operator==(const FragmentRuntimeInfo& other) const noexcept {
|
||||
return std::ranges::equal(color_buffers, other.color_buffers) &&
|
||||
en_flags.raw == other.en_flags.raw && addr_flags.raw == other.addr_flags.raw &&
|
||||
num_inputs == other.num_inputs &&
|
||||
std::ranges::equal(inputs.begin(), inputs.begin() + num_inputs, other.inputs.begin(),
|
||||
other.inputs.begin() + num_inputs);
|
||||
|
|
|
@ -1071,6 +1071,28 @@ struct Liverpool {
|
|||
BitField<27, 1, u32> enable_postz_overrasterization;
|
||||
};
|
||||
|
||||
union PsInput {
|
||||
u32 raw;
|
||||
struct {
|
||||
u32 persp_sample_ena : 1;
|
||||
u32 persp_center_ena : 1;
|
||||
u32 persp_centroid_ena : 1;
|
||||
u32 persp_pull_model_ena : 1;
|
||||
u32 linear_sample_ena : 1;
|
||||
u32 linear_center_ena : 1;
|
||||
u32 linear_centroid_ena : 1;
|
||||
u32 line_stipple_tex_ena : 1;
|
||||
u32 pos_x_float_ena : 1;
|
||||
u32 pos_y_float_ena : 1;
|
||||
u32 pos_z_float_ena : 1;
|
||||
u32 pos_w_float_ena : 1;
|
||||
u32 front_face_ena : 1;
|
||||
u32 ancillary_ena : 1;
|
||||
u32 sample_coverage_ena : 1;
|
||||
u32 pos_fixed_pt_ena : 1;
|
||||
};
|
||||
};
|
||||
|
||||
union Regs {
|
||||
struct {
|
||||
INSERT_PADDING_WORDS(0x2C08);
|
||||
|
@ -1126,7 +1148,10 @@ struct Liverpool {
|
|||
INSERT_PADDING_WORDS(0xA191 - 0xA187);
|
||||
std::array<PsInputControl, 32> ps_inputs;
|
||||
VsOutputConfig vs_output_config;
|
||||
INSERT_PADDING_WORDS(4);
|
||||
INSERT_PADDING_WORDS(1);
|
||||
PsInput ps_input_ena;
|
||||
PsInput ps_input_addr;
|
||||
INSERT_PADDING_WORDS(1);
|
||||
BitField<0, 6, u32> num_interp;
|
||||
INSERT_PADDING_WORDS(0xA1C3 - 0xA1B6 - 1);
|
||||
ShaderPosFormat shader_pos_format;
|
||||
|
@ -1388,6 +1413,8 @@ static_assert(GFX6_3D_REG_INDEX(viewports) == 0xA10F);
|
|||
static_assert(GFX6_3D_REG_INDEX(clip_user_data) == 0xA16F);
|
||||
static_assert(GFX6_3D_REG_INDEX(ps_inputs) == 0xA191);
|
||||
static_assert(GFX6_3D_REG_INDEX(vs_output_config) == 0xA1B1);
|
||||
static_assert(GFX6_3D_REG_INDEX(ps_input_ena) == 0xA1B3);
|
||||
static_assert(GFX6_3D_REG_INDEX(ps_input_addr) == 0xA1B4);
|
||||
static_assert(GFX6_3D_REG_INDEX(num_interp) == 0xA1B6);
|
||||
static_assert(GFX6_3D_REG_INDEX(shader_pos_format) == 0xA1C3);
|
||||
static_assert(GFX6_3D_REG_INDEX(z_export_format) == 0xA1C4);
|
||||
|
|
|
@ -123,6 +123,8 @@ Shader::RuntimeInfo PipelineCache::BuildRuntimeInfo(Shader::Stage stage) {
|
|||
}
|
||||
case Shader::Stage::Fragment: {
|
||||
BuildCommon(regs.ps_program);
|
||||
info.fs_info.en_flags = regs.ps_input_ena;
|
||||
info.fs_info.addr_flags = regs.ps_input_addr;
|
||||
const auto& ps_inputs = regs.ps_inputs;
|
||||
info.fs_info.num_inputs = regs.num_interp;
|
||||
for (u32 i = 0; i < regs.num_interp; i++) {
|
||||
|
|
Loading…
Reference in a new issue