handle other registers as well

This commit is contained in:
Vladislav Mikhalin 2024-12-06 20:34:00 +03:00
parent dcf659735e
commit 81a5062ee9
4 changed files with 89 additions and 70 deletions

View File

@ -53,28 +53,73 @@ void Translator::EmitPrologue() {
} }
break; break;
case Stage::Fragment: case Stage::Fragment:
// https://github.com/chaotic-cx/mesa-mirror/blob/72326e15/src/amd/vulkan/radv_shader_args.c#L258 dst_vreg = IR::VectorReg::V0;
// The first two VGPRs are used for i/j barycentric coordinates. In the vast majority of if (runtime_info.fs_info.addr_flags.persp_sample_ena) {
// cases it will be only those two, but if shader is using both e.g linear and perspective ++dst_vreg; // I
// inputs it can be more For now assume that this isn't the case. ++dst_vreg; // J
dst_vreg = IR::VectorReg::V2; }
for (u32 i = 0; i < 4; i++) { if (runtime_info.fs_info.addr_flags.persp_center_ena) {
if (True(runtime_info.fs_info.addr_flags & Shader::PsInputFlags(1 << i))) { ++dst_vreg; // I
if (True(runtime_info.fs_info.en_flags & Shader::PsInputFlags(1 << i))) { ++dst_vreg; // J
ir.SetVectorReg(dst_vreg, ir.GetAttribute(IR::Attribute::FragCoord, i)); }
} else { if (runtime_info.fs_info.addr_flags.persp_centroid_ena) {
ir.SetVectorReg(dst_vreg, ir.Imm32(0.0f)); ++dst_vreg; // I
} ++dst_vreg; // J
++dst_vreg; }
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 (True(runtime_info.fs_info.addr_flags & Shader::PsInputFlags::FrontFacing)) { if (runtime_info.fs_info.addr_flags.pos_y_float_ena) {
if (True(runtime_info.fs_info.en_flags & Shader::PsInputFlags::FrontFacing)) { if (runtime_info.fs_info.en_flags.pos_y_float_ena) {
ir.SetVectorReg(dst_vreg, ir.GetAttributeU32(IR::Attribute::IsFrontFace)); ir.SetVectorReg(dst_vreg++, ir.GetAttribute(IR::Attribute::FragCoord, 1));
} else { } else {
ir.SetVectorReg(dst_vreg, ir.Imm32(0)); 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));
} }
++dst_vreg;
} }
break; break;
case Stage::Compute: case Stage::Compute:

View File

@ -7,6 +7,7 @@
#include <span> #include <span>
#include <boost/container/static_vector.hpp> #include <boost/container/static_vector.hpp>
#include "common/types.h" #include "common/types.h"
#include "video_core/amdgpu/liverpool.h"
#include "video_core/amdgpu/types.h" #include "video_core/amdgpu/types.h"
namespace Shader { namespace Shader {
@ -96,16 +97,6 @@ enum class MrtSwizzle : u8 {
}; };
static constexpr u32 MaxColorBuffers = 8; static constexpr u32 MaxColorBuffers = 8;
enum class PsInputFlags : u8 {
None = 0,
PosX = 1 << 0,
PosY = 1 << 1,
PosZ = 1 << 2,
PosW = 1 << 3,
FrontFacing = 1 << 4,
};
DECLARE_ENUM_FLAG_OPERATORS(PsInputFlags)
struct FragmentRuntimeInfo { struct FragmentRuntimeInfo {
struct PsInput { struct PsInput {
u8 param_index; u8 param_index;
@ -115,8 +106,8 @@ struct FragmentRuntimeInfo {
auto operator<=>(const PsInput&) const noexcept = default; auto operator<=>(const PsInput&) const noexcept = default;
}; };
PsInputFlags en_flags; AmdGpu::Liverpool::PsInput en_flags;
PsInputFlags addr_flags; AmdGpu::Liverpool::PsInput addr_flags;
u32 num_inputs; u32 num_inputs;
std::array<PsInput, 32> inputs; std::array<PsInput, 32> inputs;
struct PsColorBuffer { struct PsColorBuffer {
@ -129,7 +120,7 @@ struct FragmentRuntimeInfo {
bool operator==(const FragmentRuntimeInfo& other) const noexcept { bool operator==(const FragmentRuntimeInfo& other) const noexcept {
return std::ranges::equal(color_buffers, other.color_buffers) && return std::ranges::equal(color_buffers, other.color_buffers) &&
en_flags == other.en_flags && addr_flags == other.addr_flags && en_flags.raw == other.en_flags.raw && addr_flags.raw == other.addr_flags.raw &&
num_inputs == other.num_inputs && num_inputs == other.num_inputs &&
std::ranges::equal(inputs.begin(), inputs.begin() + num_inputs, other.inputs.begin(), std::ranges::equal(inputs.begin(), inputs.begin() + num_inputs, other.inputs.begin(),
other.inputs.begin() + num_inputs); other.inputs.begin() + num_inputs);

View File

@ -1071,23 +1071,26 @@ struct Liverpool {
BitField<27, 1, u32> enable_postz_overrasterization; BitField<27, 1, u32> enable_postz_overrasterization;
}; };
struct PsInput { union PsInput {
u32 persp_sample_ena : 1; u32 raw;
u32 persp_center_ena : 1; struct {
u32 persp_centroid_ena : 1; u32 persp_sample_ena : 1;
u32 persp_pull_model_ena : 1; u32 persp_center_ena : 1;
u32 linear_sample_ena : 1; u32 persp_centroid_ena : 1;
u32 linear_center_ena : 1; u32 persp_pull_model_ena : 1;
u32 linear_centroid_ena : 1; u32 linear_sample_ena : 1;
u32 line_stipple_tex_ena : 1; u32 linear_center_ena : 1;
u32 pos_x_float_ena : 1; u32 linear_centroid_ena : 1;
u32 pos_y_float_ena : 1; u32 line_stipple_tex_ena : 1;
u32 pos_z_float_ena : 1; u32 pos_x_float_ena : 1;
u32 pos_w_float_ena : 1; u32 pos_y_float_ena : 1;
u32 front_face_ena : 1; u32 pos_z_float_ena : 1;
u32 ancillary_ena : 1; u32 pos_w_float_ena : 1;
u32 sample_coverage_ena : 1; u32 front_face_ena : 1;
u32 pos_fixed_pt_ena : 1; u32 ancillary_ena : 1;
u32 sample_coverage_ena : 1;
u32 pos_fixed_pt_ena : 1;
};
}; };
union Regs { union Regs {

View File

@ -123,28 +123,8 @@ Shader::RuntimeInfo PipelineCache::BuildRuntimeInfo(Shader::Stage stage) {
} }
case Shader::Stage::Fragment: { case Shader::Stage::Fragment: {
BuildCommon(regs.ps_program); BuildCommon(regs.ps_program);
info.fs_info.en_flags = info.fs_info.en_flags = regs.ps_input_ena;
(regs.ps_input_ena.pos_x_float_ena ? Shader::PsInputFlags::PosX info.fs_info.addr_flags = regs.ps_input_addr;
: Shader::PsInputFlags::None) |
(regs.ps_input_ena.pos_y_float_ena ? Shader::PsInputFlags::PosY
: Shader::PsInputFlags::None) |
(regs.ps_input_ena.pos_z_float_ena ? Shader::PsInputFlags::PosZ
: Shader::PsInputFlags::None) |
(regs.ps_input_ena.pos_w_float_ena ? Shader::PsInputFlags::PosW
: Shader::PsInputFlags::None) |
(regs.ps_input_ena.front_face_ena ? Shader::PsInputFlags::FrontFacing
: Shader::PsInputFlags::None);
info.fs_info.addr_flags =
(regs.ps_input_addr.pos_x_float_ena ? Shader::PsInputFlags::PosX
: Shader::PsInputFlags::None) |
(regs.ps_input_addr.pos_y_float_ena ? Shader::PsInputFlags::PosY
: Shader::PsInputFlags::None) |
(regs.ps_input_addr.pos_z_float_ena ? Shader::PsInputFlags::PosZ
: Shader::PsInputFlags::None) |
(regs.ps_input_addr.pos_w_float_ena ? Shader::PsInputFlags::PosW
: Shader::PsInputFlags::None) |
(regs.ps_input_addr.front_face_ena ? Shader::PsInputFlags::FrontFacing
: Shader::PsInputFlags::None);
const auto& ps_inputs = regs.ps_inputs; const auto& ps_inputs = regs.ps_inputs;
info.fs_info.num_inputs = regs.num_interp; info.fs_info.num_inputs = regs.num_interp;
for (u32 i = 0; i < regs.num_interp; i++) { for (u32 i = 0; i < regs.num_interp; i++) {