mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 18:15:14 +00:00
Review comments and some cleanup
This commit is contained in:
parent
3b0d08c730
commit
f3e2d985f7
@ -294,11 +294,11 @@ void SetupCapabilities(const Info& info, const Profile& profile, EmitContext& ct
|
||||
ctx.AddCapability(spv::Capability::Geometry);
|
||||
}
|
||||
if (info.stage == Stage::Fragment) {
|
||||
if (profile.supports_fragment_shader_barycentric) {
|
||||
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
||||
ctx.AddExtension("SPV_AMD_shader_explicit_vertex_parameter");
|
||||
} else if (profile.supports_fragment_shader_barycentric) {
|
||||
ctx.AddExtension("SPV_KHR_fragment_shader_barycentric");
|
||||
ctx.AddCapability(spv::Capability::FragmentBarycentricKHR);
|
||||
} else if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
||||
ctx.AddExtension("SPV_AMD_shader_explicit_vertex_parameter");
|
||||
}
|
||||
if (info.loads.GetAny(IR::Attribute::BaryCoordSmoothSample) ||
|
||||
info.loads.GetAny(IR::Attribute::BaryCoordNoPerspSample)) {
|
||||
|
@ -68,7 +68,7 @@ Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr, u32 element) {
|
||||
}
|
||||
if (IR::IsMrt(attr)) {
|
||||
const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)};
|
||||
const auto& info{ctx.output_params.at(index)};
|
||||
const auto& info{ctx.frag_outputs.at(index)};
|
||||
if (info.num_components == 1) {
|
||||
return info.id;
|
||||
} else {
|
||||
@ -100,7 +100,7 @@ std::pair<Id, bool> OutputAttrComponentType(EmitContext& ctx, IR::Attribute attr
|
||||
}
|
||||
if (IR::IsMrt(attr)) {
|
||||
const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)};
|
||||
const auto& info{ctx.output_params.at(index)};
|
||||
const auto& info{ctx.frag_outputs.at(index)};
|
||||
return {info.component_type, info.is_integer};
|
||||
}
|
||||
switch (attr) {
|
||||
@ -163,7 +163,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) {
|
||||
if (IR::IsParam(attr)) {
|
||||
const u32 param_index{u32(attr) - u32(IR::Attribute::Param0)};
|
||||
const auto& param{ctx.input_params.at(param_index)};
|
||||
const Id result = [&] {
|
||||
const Id value = [&] {
|
||||
if (param.is_array) {
|
||||
ASSERT(param.num_components > 1);
|
||||
if (param.is_loaded) {
|
||||
@ -185,7 +185,10 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) {
|
||||
}
|
||||
}
|
||||
}();
|
||||
return param.is_integer ? ctx.OpBitcast(ctx.F32[1], result) : result;
|
||||
return param.is_integer ? ctx.OpBitcast(ctx.F32[1], value) : value;
|
||||
}
|
||||
if (IR::IsBarycentricCoord(attr) && ctx.profile.supports_fragment_shader_barycentric) {
|
||||
++comp;
|
||||
}
|
||||
switch (attr) {
|
||||
case IR::Attribute::Position0:
|
||||
@ -203,21 +206,12 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) {
|
||||
return ctx.OpLoad(ctx.F32[1],
|
||||
ctx.OpAccessChain(ctx.input_f32, ctx.tess_coord, ctx.ConstU32(1U)));
|
||||
case IR::Attribute::BaryCoordSmooth:
|
||||
if (ctx.profile.supports_fragment_shader_barycentric) {
|
||||
++comp;
|
||||
}
|
||||
return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth,
|
||||
ctx.ConstU32(comp)));
|
||||
case IR::Attribute::BaryCoordSmoothSample:
|
||||
if (ctx.profile.supports_fragment_shader_barycentric) {
|
||||
++comp;
|
||||
}
|
||||
return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_sample,
|
||||
ctx.ConstU32(comp)));
|
||||
case IR::Attribute::BaryCoordNoPersp:
|
||||
if (ctx.profile.supports_fragment_shader_barycentric) {
|
||||
++comp;
|
||||
}
|
||||
return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_nopersp,
|
||||
ctx.ConstU32(comp)));
|
||||
default:
|
||||
|
@ -305,7 +305,7 @@ void EmitContext::DefineAmdPerVertexAttribs() {
|
||||
}
|
||||
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
|
||||
const auto& input = runtime_info.fs_info.inputs[i];
|
||||
if (input.IsDefault() || info.fs_interp_qualifiers[i].primary != Qualifier::PerVertex) {
|
||||
if (input.IsDefault() || info.fs_interpolation[i].primary != Qualifier::PerVertex) {
|
||||
continue;
|
||||
}
|
||||
auto& param = input_params[i];
|
||||
@ -316,6 +316,7 @@ void EmitContext::DefineAmdPerVertexAttribs() {
|
||||
OpInterpolateAtVertexAMD(F32[param.num_components], pointer, ConstU32(1U));
|
||||
param.id_array[2] =
|
||||
OpInterpolateAtVertexAMD(F32[param.num_components], pointer, ConstU32(2U));
|
||||
param.is_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -378,28 +379,34 @@ void EmitContext::DefineInputs() {
|
||||
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
||||
bary_coord_smooth = DefineVariable(F32[2], spv::BuiltIn::BaryCoordSmoothAMD,
|
||||
spv::StorageClass::Input);
|
||||
} else {
|
||||
} else if (profile.supports_fragment_shader_barycentric) {
|
||||
bary_coord_smooth =
|
||||
DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input);
|
||||
} else {
|
||||
bary_coord_smooth = ConstF32(0.f, 0.f);
|
||||
}
|
||||
}
|
||||
if (info.loads.GetAny(IR::Attribute::BaryCoordSmoothSample)) {
|
||||
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
||||
bary_coord_smooth = DefineVariable(F32[2], spv::BuiltIn::BaryCoordSmoothSampleAMD,
|
||||
spv::StorageClass::Input);
|
||||
} else {
|
||||
bary_coord_smooth_sample = DefineVariable(
|
||||
F32[2], spv::BuiltIn::BaryCoordSmoothSampleAMD, spv::StorageClass::Input);
|
||||
} else if (profile.supports_fragment_shader_barycentric) {
|
||||
bary_coord_smooth_sample =
|
||||
DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input);
|
||||
// Decorate(bary_coord_smooth_sample, spv::Decoration::Sample);
|
||||
} else {
|
||||
bary_coord_smooth_sample = ConstF32(0.f, 0.f);
|
||||
}
|
||||
}
|
||||
if (info.loads.GetAny(IR::Attribute::BaryCoordNoPersp)) {
|
||||
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
||||
bary_coord_nopersp = DefineVariable(F32[2], spv::BuiltIn::BaryCoordNoPerspAMD,
|
||||
spv::StorageClass::Input);
|
||||
} else {
|
||||
} else if (profile.supports_fragment_shader_barycentric) {
|
||||
bary_coord_nopersp = DefineVariable(F32[3], spv::BuiltIn::BaryCoordNoPerspKHR,
|
||||
spv::StorageClass::Input);
|
||||
} else {
|
||||
bary_coord_nopersp = ConstF32(0.f, 0.f);
|
||||
}
|
||||
}
|
||||
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
|
||||
@ -409,36 +416,30 @@ void EmitContext::DefineInputs() {
|
||||
}
|
||||
const IR::Attribute param = IR::Attribute::Param0 + i;
|
||||
const u32 num_components = info.loads.NumComponents(param);
|
||||
const auto [primary, auxiliary] = info.fs_interp_qualifiers[i];
|
||||
const bool is_array = primary == Qualifier::PerVertex;
|
||||
const Id type{F32[num_components]};
|
||||
Id attr_id{};
|
||||
// Declare primary qualifier (pervertex, smooth, noperspective, flat)
|
||||
if (is_array) {
|
||||
if (profile.supports_fragment_shader_barycentric) {
|
||||
attr_id = DefineInput(TypeArray(type, ConstU32(3U)), input.param_index);
|
||||
Decorate(attr_id, spv::Decoration::PerVertexKHR);
|
||||
} else {
|
||||
attr_id = DefineInput(type, input.param_index);
|
||||
Decorate(attr_id, spv::Decoration::ExplicitInterpAMD);
|
||||
}
|
||||
Name(attr_id, fmt::format("fs_in_attr{}_p", i));
|
||||
} else {
|
||||
attr_id = DefineInput(type, input.param_index);
|
||||
Name(attr_id, fmt::format("fs_in_attr{}", i));
|
||||
if (primary != Qualifier::Smooth) {
|
||||
Decorate(attr_id, primary == Qualifier::Flat ? spv::Decoration::Flat
|
||||
: spv::Decoration::NoPerspective);
|
||||
const auto [primary, auxiliary] = info.fs_interpolation[i];
|
||||
const Id type = F32[num_components];
|
||||
const Id attr_id = [&] {
|
||||
if (primary == Qualifier::PerVertex &&
|
||||
profile.supports_fragment_shader_barycentric) {
|
||||
return Name(DefineInput(TypeArray(type, ConstU32(3U)), input.param_index),
|
||||
fmt::format("fs_in_attr{}_p", i));
|
||||
}
|
||||
return Name(DefineInput(type, input.param_index), fmt::format("fs_in_attr{}", i));
|
||||
}();
|
||||
if (primary == Qualifier::PerVertex) {
|
||||
Decorate(attr_id, profile.supports_amd_shader_explicit_vertex_parameter
|
||||
? spv::Decoration::ExplicitInterpAMD
|
||||
: spv::Decoration::PerVertexKHR);
|
||||
} else if (primary != Qualifier::Smooth) {
|
||||
Decorate(attr_id, primary == Qualifier::Flat ? spv::Decoration::Flat
|
||||
: spv::Decoration::NoPerspective);
|
||||
}
|
||||
// Declare auxiliary qualifier if present (centroid, sample)
|
||||
if (auxiliary != Qualifier::None) {
|
||||
Decorate(attr_id, auxiliary == Qualifier::Centroid ? spv::Decoration::Centroid
|
||||
: spv::Decoration::Sample);
|
||||
}
|
||||
input_params[i] = GetAttributeInfo(
|
||||
AmdGpu::NumberFormat::Float, attr_id, num_components, false,
|
||||
is_array && profile.supports_amd_shader_explicit_vertex_parameter, is_array);
|
||||
input_params[i] = GetAttributeInfo(AmdGpu::NumberFormat::Float, attr_id, num_components,
|
||||
false, false, primary == Qualifier::PerVertex);
|
||||
}
|
||||
break;
|
||||
case LogicalStage::Compute:
|
||||
@ -650,7 +651,7 @@ void EmitContext::DefineOutputs() {
|
||||
id = DefineOutput(type, i);
|
||||
}
|
||||
Name(id, fmt::format("frag_color{}", i));
|
||||
output_params[i] = GetAttributeInfo(num_format, id, num_components, true);
|
||||
frag_outputs[i] = GetAttributeInfo(num_format, id, num_components, true);
|
||||
++num_render_targets;
|
||||
}
|
||||
ASSERT_MSG(!runtime_info.fs_info.dual_source_blending || num_render_targets == 2,
|
||||
|
@ -371,6 +371,7 @@ public:
|
||||
Id output_attr_array;
|
||||
std::array<SpirvAttribute, IR::NumParams> input_params{};
|
||||
std::array<SpirvAttribute, IR::NumParams> output_params{};
|
||||
std::array<SpirvAttribute, IR::NumRenderTargets> frag_outputs{};
|
||||
|
||||
Id uf11_to_f32{};
|
||||
Id f32_to_uf11{};
|
||||
|
@ -60,7 +60,7 @@ void Translator::V_INTERP_P2_F32(const GcnInst& inst) {
|
||||
const u32 attr_index = inst.control.vintrp.attr;
|
||||
const IR::Attribute attrib = IR::Attribute::Param0 + attr_index;
|
||||
const auto& attr = runtime_info.fs_info.inputs[attr_index];
|
||||
auto& interp = info.fs_interp_qualifiers[attr_index];
|
||||
auto& interp = info.fs_interpolation[attr_index];
|
||||
ASSERT(!attr.IsDefault() && !attr.is_flat);
|
||||
if (!profile.needs_manual_interpolation) {
|
||||
interp = GetInterpolation(vgpr_to_interp[inst.src[0].code]);
|
||||
@ -80,10 +80,11 @@ void Translator::V_INTERP_MOV_F32(const GcnInst& inst) {
|
||||
const u32 attr_index = inst.control.vintrp.attr;
|
||||
const IR::Attribute attrib = IR::Attribute::Param0 + attr_index;
|
||||
const auto& attr = runtime_info.fs_info.inputs[attr_index];
|
||||
auto& interp = info.fs_interp_qualifiers[attr_index];
|
||||
auto& interp = info.fs_interpolation[attr_index];
|
||||
ASSERT(attr.is_flat);
|
||||
if (profile.supports_amd_shader_explicit_vertex_parameter ||
|
||||
profile.supports_fragment_shader_barycentric) {
|
||||
(profile.supports_fragment_shader_barycentric &&
|
||||
!profile.has_incomplete_fragment_shader_barycentric)) {
|
||||
// VSRC 0=P10, 1=P20, 2=P0
|
||||
interp.primary = Qualifier::PerVertex;
|
||||
SetDst(inst.dst[0],
|
||||
|
@ -209,7 +209,7 @@ struct Info {
|
||||
Qualifier primary;
|
||||
Qualifier auxiliary;
|
||||
};
|
||||
std::array<Interpolation, IR::NumParams> fs_interp_qualifiers{};
|
||||
std::array<Interpolation, IR::NumParams> fs_interpolation{};
|
||||
|
||||
IR::ScalarReg tess_consts_ptr_base = IR::ScalarReg::Max;
|
||||
s32 tess_consts_dword_offset = -1;
|
||||
|
@ -109,12 +109,7 @@ constexpr bool IsMrt(Attribute attribute) noexcept {
|
||||
return attribute >= Attribute::RenderTarget0 && attribute <= Attribute::RenderTarget7;
|
||||
}
|
||||
|
||||
constexpr bool IsLinear(Attribute attribute) noexcept {
|
||||
return attribute >= Attribute::BaryCoordNoPersp &&
|
||||
attribute <= Attribute::BaryCoordNoPerspSample;
|
||||
}
|
||||
|
||||
constexpr bool IsPerspective(Attribute attribute) noexcept {
|
||||
constexpr bool IsBarycentricCoord(Attribute attribute) noexcept {
|
||||
return attribute >= Attribute::BaryCoordSmooth && attribute <= Attribute::BaryCoordSmoothSample;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ struct Profile {
|
||||
bool supports_workgroup_explicit_memory_layout{};
|
||||
bool supports_amd_shader_explicit_vertex_parameter{};
|
||||
bool supports_fragment_shader_barycentric{};
|
||||
bool has_incomplete_fragment_shader_barycentric{};
|
||||
bool has_broken_spirv_clamp{};
|
||||
bool lower_left_origin_mode{};
|
||||
bool needs_manual_interpolation{};
|
||||
|
@ -223,6 +223,9 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
|
||||
.supports_amd_shader_explicit_vertex_parameter =
|
||||
instance_.IsAmdShaderExplicitVertexParameterSupported(),
|
||||
.supports_fragment_shader_barycentric = instance_.IsFragmentShaderBarycentricSupported(),
|
||||
.has_incomplete_fragment_shader_barycentric =
|
||||
instance_.IsFragmentShaderBarycentricSupported() &&
|
||||
instance.GetDriverID() == vk::DriverId::eMoltenvk,
|
||||
.needs_manual_interpolation = instance.IsFragmentShaderBarycentricSupported() &&
|
||||
instance.GetDriverID() == vk::DriverId::eNvidiaProprietary,
|
||||
.needs_lds_barriers = instance.GetDriverID() == vk::DriverId::eNvidiaProprietary ||
|
||||
|
Loading…
Reference in New Issue
Block a user