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);
|
ctx.AddCapability(spv::Capability::Geometry);
|
||||||
}
|
}
|
||||||
if (info.stage == Stage::Fragment) {
|
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.AddExtension("SPV_KHR_fragment_shader_barycentric");
|
||||||
ctx.AddCapability(spv::Capability::FragmentBarycentricKHR);
|
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) ||
|
if (info.loads.GetAny(IR::Attribute::BaryCoordSmoothSample) ||
|
||||||
info.loads.GetAny(IR::Attribute::BaryCoordNoPerspSample)) {
|
info.loads.GetAny(IR::Attribute::BaryCoordNoPerspSample)) {
|
||||||
|
@ -68,7 +68,7 @@ Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr, u32 element) {
|
|||||||
}
|
}
|
||||||
if (IR::IsMrt(attr)) {
|
if (IR::IsMrt(attr)) {
|
||||||
const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)};
|
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) {
|
if (info.num_components == 1) {
|
||||||
return info.id;
|
return info.id;
|
||||||
} else {
|
} else {
|
||||||
@ -100,7 +100,7 @@ std::pair<Id, bool> OutputAttrComponentType(EmitContext& ctx, IR::Attribute attr
|
|||||||
}
|
}
|
||||||
if (IR::IsMrt(attr)) {
|
if (IR::IsMrt(attr)) {
|
||||||
const u32 index{u32(attr) - u32(IR::Attribute::RenderTarget0)};
|
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};
|
return {info.component_type, info.is_integer};
|
||||||
}
|
}
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
@ -163,7 +163,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) {
|
|||||||
if (IR::IsParam(attr)) {
|
if (IR::IsParam(attr)) {
|
||||||
const u32 param_index{u32(attr) - u32(IR::Attribute::Param0)};
|
const u32 param_index{u32(attr) - u32(IR::Attribute::Param0)};
|
||||||
const auto& param{ctx.input_params.at(param_index)};
|
const auto& param{ctx.input_params.at(param_index)};
|
||||||
const Id result = [&] {
|
const Id value = [&] {
|
||||||
if (param.is_array) {
|
if (param.is_array) {
|
||||||
ASSERT(param.num_components > 1);
|
ASSERT(param.num_components > 1);
|
||||||
if (param.is_loaded) {
|
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) {
|
switch (attr) {
|
||||||
case IR::Attribute::Position0:
|
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],
|
return ctx.OpLoad(ctx.F32[1],
|
||||||
ctx.OpAccessChain(ctx.input_f32, ctx.tess_coord, ctx.ConstU32(1U)));
|
ctx.OpAccessChain(ctx.input_f32, ctx.tess_coord, ctx.ConstU32(1U)));
|
||||||
case IR::Attribute::BaryCoordSmooth:
|
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,
|
return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth,
|
||||||
ctx.ConstU32(comp)));
|
ctx.ConstU32(comp)));
|
||||||
case IR::Attribute::BaryCoordSmoothSample:
|
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,
|
return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_smooth_sample,
|
||||||
ctx.ConstU32(comp)));
|
ctx.ConstU32(comp)));
|
||||||
case IR::Attribute::BaryCoordNoPersp:
|
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,
|
return ctx.OpLoad(ctx.F32[1], ctx.OpAccessChain(ctx.input_f32, ctx.bary_coord_nopersp,
|
||||||
ctx.ConstU32(comp)));
|
ctx.ConstU32(comp)));
|
||||||
default:
|
default:
|
||||||
|
@ -305,7 +305,7 @@ void EmitContext::DefineAmdPerVertexAttribs() {
|
|||||||
}
|
}
|
||||||
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
|
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
|
||||||
const auto& input = runtime_info.fs_info.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;
|
continue;
|
||||||
}
|
}
|
||||||
auto& param = input_params[i];
|
auto& param = input_params[i];
|
||||||
@ -316,6 +316,7 @@ void EmitContext::DefineAmdPerVertexAttribs() {
|
|||||||
OpInterpolateAtVertexAMD(F32[param.num_components], pointer, ConstU32(1U));
|
OpInterpolateAtVertexAMD(F32[param.num_components], pointer, ConstU32(1U));
|
||||||
param.id_array[2] =
|
param.id_array[2] =
|
||||||
OpInterpolateAtVertexAMD(F32[param.num_components], pointer, ConstU32(2U));
|
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) {
|
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
||||||
bary_coord_smooth = DefineVariable(F32[2], spv::BuiltIn::BaryCoordSmoothAMD,
|
bary_coord_smooth = DefineVariable(F32[2], spv::BuiltIn::BaryCoordSmoothAMD,
|
||||||
spv::StorageClass::Input);
|
spv::StorageClass::Input);
|
||||||
} else {
|
} else if (profile.supports_fragment_shader_barycentric) {
|
||||||
bary_coord_smooth =
|
bary_coord_smooth =
|
||||||
DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input);
|
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 (info.loads.GetAny(IR::Attribute::BaryCoordSmoothSample)) {
|
||||||
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
||||||
bary_coord_smooth = DefineVariable(F32[2], spv::BuiltIn::BaryCoordSmoothSampleAMD,
|
bary_coord_smooth_sample = DefineVariable(
|
||||||
spv::StorageClass::Input);
|
F32[2], spv::BuiltIn::BaryCoordSmoothSampleAMD, spv::StorageClass::Input);
|
||||||
} else {
|
} else if (profile.supports_fragment_shader_barycentric) {
|
||||||
bary_coord_smooth_sample =
|
bary_coord_smooth_sample =
|
||||||
DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input);
|
DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input);
|
||||||
// Decorate(bary_coord_smooth_sample, spv::Decoration::Sample);
|
// 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 (info.loads.GetAny(IR::Attribute::BaryCoordNoPersp)) {
|
||||||
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
if (profile.supports_amd_shader_explicit_vertex_parameter) {
|
||||||
bary_coord_nopersp = DefineVariable(F32[2], spv::BuiltIn::BaryCoordNoPerspAMD,
|
bary_coord_nopersp = DefineVariable(F32[2], spv::BuiltIn::BaryCoordNoPerspAMD,
|
||||||
spv::StorageClass::Input);
|
spv::StorageClass::Input);
|
||||||
} else {
|
} else if (profile.supports_fragment_shader_barycentric) {
|
||||||
bary_coord_nopersp = DefineVariable(F32[3], spv::BuiltIn::BaryCoordNoPerspKHR,
|
bary_coord_nopersp = DefineVariable(F32[3], spv::BuiltIn::BaryCoordNoPerspKHR,
|
||||||
spv::StorageClass::Input);
|
spv::StorageClass::Input);
|
||||||
|
} else {
|
||||||
|
bary_coord_nopersp = ConstF32(0.f, 0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
|
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 IR::Attribute param = IR::Attribute::Param0 + i;
|
||||||
const u32 num_components = info.loads.NumComponents(param);
|
const u32 num_components = info.loads.NumComponents(param);
|
||||||
const auto [primary, auxiliary] = info.fs_interp_qualifiers[i];
|
const auto [primary, auxiliary] = info.fs_interpolation[i];
|
||||||
const bool is_array = primary == Qualifier::PerVertex;
|
const Id type = F32[num_components];
|
||||||
const Id type{F32[num_components]};
|
const Id attr_id = [&] {
|
||||||
Id attr_id{};
|
if (primary == Qualifier::PerVertex &&
|
||||||
// Declare primary qualifier (pervertex, smooth, noperspective, flat)
|
profile.supports_fragment_shader_barycentric) {
|
||||||
if (is_array) {
|
return Name(DefineInput(TypeArray(type, ConstU32(3U)), input.param_index),
|
||||||
if (profile.supports_fragment_shader_barycentric) {
|
fmt::format("fs_in_attr{}_p", i));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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) {
|
if (auxiliary != Qualifier::None) {
|
||||||
Decorate(attr_id, auxiliary == Qualifier::Centroid ? spv::Decoration::Centroid
|
Decorate(attr_id, auxiliary == Qualifier::Centroid ? spv::Decoration::Centroid
|
||||||
: spv::Decoration::Sample);
|
: spv::Decoration::Sample);
|
||||||
}
|
}
|
||||||
input_params[i] = GetAttributeInfo(
|
input_params[i] = GetAttributeInfo(AmdGpu::NumberFormat::Float, attr_id, num_components,
|
||||||
AmdGpu::NumberFormat::Float, attr_id, num_components, false,
|
false, false, primary == Qualifier::PerVertex);
|
||||||
is_array && profile.supports_amd_shader_explicit_vertex_parameter, is_array);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LogicalStage::Compute:
|
case LogicalStage::Compute:
|
||||||
@ -650,7 +651,7 @@ void EmitContext::DefineOutputs() {
|
|||||||
id = DefineOutput(type, i);
|
id = DefineOutput(type, i);
|
||||||
}
|
}
|
||||||
Name(id, fmt::format("frag_color{}", 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;
|
++num_render_targets;
|
||||||
}
|
}
|
||||||
ASSERT_MSG(!runtime_info.fs_info.dual_source_blending || num_render_targets == 2,
|
ASSERT_MSG(!runtime_info.fs_info.dual_source_blending || num_render_targets == 2,
|
||||||
|
@ -371,6 +371,7 @@ public:
|
|||||||
Id output_attr_array;
|
Id output_attr_array;
|
||||||
std::array<SpirvAttribute, IR::NumParams> input_params{};
|
std::array<SpirvAttribute, IR::NumParams> input_params{};
|
||||||
std::array<SpirvAttribute, IR::NumParams> output_params{};
|
std::array<SpirvAttribute, IR::NumParams> output_params{};
|
||||||
|
std::array<SpirvAttribute, IR::NumRenderTargets> frag_outputs{};
|
||||||
|
|
||||||
Id uf11_to_f32{};
|
Id uf11_to_f32{};
|
||||||
Id f32_to_uf11{};
|
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 u32 attr_index = inst.control.vintrp.attr;
|
||||||
const IR::Attribute attrib = IR::Attribute::Param0 + attr_index;
|
const IR::Attribute attrib = IR::Attribute::Param0 + attr_index;
|
||||||
const auto& attr = runtime_info.fs_info.inputs[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);
|
ASSERT(!attr.IsDefault() && !attr.is_flat);
|
||||||
if (!profile.needs_manual_interpolation) {
|
if (!profile.needs_manual_interpolation) {
|
||||||
interp = GetInterpolation(vgpr_to_interp[inst.src[0].code]);
|
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 u32 attr_index = inst.control.vintrp.attr;
|
||||||
const IR::Attribute attrib = IR::Attribute::Param0 + attr_index;
|
const IR::Attribute attrib = IR::Attribute::Param0 + attr_index;
|
||||||
const auto& attr = runtime_info.fs_info.inputs[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);
|
ASSERT(attr.is_flat);
|
||||||
if (profile.supports_amd_shader_explicit_vertex_parameter ||
|
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
|
// VSRC 0=P10, 1=P20, 2=P0
|
||||||
interp.primary = Qualifier::PerVertex;
|
interp.primary = Qualifier::PerVertex;
|
||||||
SetDst(inst.dst[0],
|
SetDst(inst.dst[0],
|
||||||
|
@ -209,7 +209,7 @@ struct Info {
|
|||||||
Qualifier primary;
|
Qualifier primary;
|
||||||
Qualifier auxiliary;
|
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;
|
IR::ScalarReg tess_consts_ptr_base = IR::ScalarReg::Max;
|
||||||
s32 tess_consts_dword_offset = -1;
|
s32 tess_consts_dword_offset = -1;
|
||||||
|
@ -109,12 +109,7 @@ constexpr bool IsMrt(Attribute attribute) noexcept {
|
|||||||
return attribute >= Attribute::RenderTarget0 && attribute <= Attribute::RenderTarget7;
|
return attribute >= Attribute::RenderTarget0 && attribute <= Attribute::RenderTarget7;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool IsLinear(Attribute attribute) noexcept {
|
constexpr bool IsBarycentricCoord(Attribute attribute) noexcept {
|
||||||
return attribute >= Attribute::BaryCoordNoPersp &&
|
|
||||||
attribute <= Attribute::BaryCoordNoPerspSample;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool IsPerspective(Attribute attribute) noexcept {
|
|
||||||
return attribute >= Attribute::BaryCoordSmooth && attribute <= Attribute::BaryCoordSmoothSample;
|
return attribute >= Attribute::BaryCoordSmooth && attribute <= Attribute::BaryCoordSmoothSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ struct Profile {
|
|||||||
bool supports_workgroup_explicit_memory_layout{};
|
bool supports_workgroup_explicit_memory_layout{};
|
||||||
bool supports_amd_shader_explicit_vertex_parameter{};
|
bool supports_amd_shader_explicit_vertex_parameter{};
|
||||||
bool supports_fragment_shader_barycentric{};
|
bool supports_fragment_shader_barycentric{};
|
||||||
|
bool has_incomplete_fragment_shader_barycentric{};
|
||||||
bool has_broken_spirv_clamp{};
|
bool has_broken_spirv_clamp{};
|
||||||
bool lower_left_origin_mode{};
|
bool lower_left_origin_mode{};
|
||||||
bool needs_manual_interpolation{};
|
bool needs_manual_interpolation{};
|
||||||
|
@ -223,6 +223,9 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
|
|||||||
.supports_amd_shader_explicit_vertex_parameter =
|
.supports_amd_shader_explicit_vertex_parameter =
|
||||||
instance_.IsAmdShaderExplicitVertexParameterSupported(),
|
instance_.IsAmdShaderExplicitVertexParameterSupported(),
|
||||||
.supports_fragment_shader_barycentric = instance_.IsFragmentShaderBarycentricSupported(),
|
.supports_fragment_shader_barycentric = instance_.IsFragmentShaderBarycentricSupported(),
|
||||||
|
.has_incomplete_fragment_shader_barycentric =
|
||||||
|
instance_.IsFragmentShaderBarycentricSupported() &&
|
||||||
|
instance.GetDriverID() == vk::DriverId::eMoltenvk,
|
||||||
.needs_manual_interpolation = instance.IsFragmentShaderBarycentricSupported() &&
|
.needs_manual_interpolation = instance.IsFragmentShaderBarycentricSupported() &&
|
||||||
instance.GetDriverID() == vk::DriverId::eNvidiaProprietary,
|
instance.GetDriverID() == vk::DriverId::eNvidiaProprietary,
|
||||||
.needs_lds_barriers = instance.GetDriverID() == vk::DriverId::eNvidiaProprietary ||
|
.needs_lds_barriers = instance.GetDriverID() == vk::DriverId::eNvidiaProprietary ||
|
||||||
|
Loading…
Reference in New Issue
Block a user