mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
shader: Implement ViewportIndex
This commit is contained in:
parent
fd496d0401
commit
d819ba4489
8 changed files with 33 additions and 2 deletions
|
@ -509,6 +509,12 @@ void EmitContext::DefineOutputs(const Info& info) {
|
||||||
const Id type{TypeArray(F32[1], Constant(U32[1], 8U))};
|
const Id type{TypeArray(F32[1], Constant(U32[1], 8U))};
|
||||||
clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance);
|
clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance);
|
||||||
}
|
}
|
||||||
|
if (info.stores_viewport_index && !ignore_viewport_layer) {
|
||||||
|
if (stage == Stage::Fragment) {
|
||||||
|
throw NotImplementedException("Storing ViewportIndex in Fragment stage");
|
||||||
|
}
|
||||||
|
viewport_index = DefineOutput(*this, U32[1], spv::BuiltIn::ViewportIndex);
|
||||||
|
}
|
||||||
for (size_t i = 0; i < info.stores_generics.size(); ++i) {
|
for (size_t i = 0; i < info.stores_generics.size(); ++i) {
|
||||||
if (info.stores_generics[i]) {
|
if (info.stores_generics[i]) {
|
||||||
output_generics[i] = DefineOutput(*this, F32[4]);
|
output_generics[i] = DefineOutput(*this, F32[4]);
|
||||||
|
|
|
@ -106,6 +106,7 @@ public:
|
||||||
Id front_face{};
|
Id front_face{};
|
||||||
Id point_coord{};
|
Id point_coord{};
|
||||||
Id clip_distances{};
|
Id clip_distances{};
|
||||||
|
Id viewport_index{};
|
||||||
|
|
||||||
Id fswzadd_lut_a{};
|
Id fswzadd_lut_a{};
|
||||||
Id fswzadd_lut_b{};
|
Id fswzadd_lut_b{};
|
||||||
|
@ -133,6 +134,8 @@ public:
|
||||||
|
|
||||||
std::vector<Id> interfaces;
|
std::vector<Id> interfaces;
|
||||||
|
|
||||||
|
bool ignore_viewport_layer{};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DefineCommonTypes(const Info& info);
|
void DefineCommonTypes(const Info& info);
|
||||||
void DefineCommonConstants();
|
void DefineCommonConstants();
|
||||||
|
|
|
@ -225,6 +225,16 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
|
||||||
ctx.AddExtension("SPV_EXT_demote_to_helper_invocation");
|
ctx.AddExtension("SPV_EXT_demote_to_helper_invocation");
|
||||||
ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT);
|
ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT);
|
||||||
}
|
}
|
||||||
|
if (info.stores_viewport_index) {
|
||||||
|
ctx.AddCapability(spv::Capability::MultiViewport);
|
||||||
|
if (profile.support_viewport_index_layer_non_geometry &&
|
||||||
|
ctx.stage == Shader::Stage::VertexB) {
|
||||||
|
ctx.AddExtension("SPV_EXT_shader_viewport_index_layer");
|
||||||
|
ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT);
|
||||||
|
} else {
|
||||||
|
ctx.ignore_viewport_layer = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) {
|
if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) {
|
||||||
ctx.AddExtension("SPV_KHR_shader_draw_parameters");
|
ctx.AddExtension("SPV_KHR_shader_draw_parameters");
|
||||||
ctx.AddCapability(spv::Capability::DrawParameters);
|
ctx.AddCapability(spv::Capability::DrawParameters);
|
||||||
|
|
|
@ -29,7 +29,7 @@ std::optional<AttrInfo> AttrTypes(EmitContext& ctx, u32 index) {
|
||||||
throw InvalidArgument("Invalid attribute type {}", type);
|
throw InvalidArgument("Invalid attribute type {}", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
|
std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
|
||||||
const u32 element{static_cast<u32>(attr) % 4};
|
const u32 element{static_cast<u32>(attr) % 4};
|
||||||
const auto element_id{[&] { return ctx.Constant(ctx.U32[1], element); }};
|
const auto element_id{[&] { return ctx.Constant(ctx.U32[1], element); }};
|
||||||
if (IR::IsGeneric(attr)) {
|
if (IR::IsGeneric(attr)) {
|
||||||
|
@ -57,6 +57,8 @@ Id OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) {
|
||||||
const Id clip_num{ctx.Constant(ctx.U32[1], index)};
|
const Id clip_num{ctx.Constant(ctx.U32[1], index)};
|
||||||
return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num);
|
return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num);
|
||||||
}
|
}
|
||||||
|
case IR::Attribute::ViewportIndex:
|
||||||
|
return ctx.ignore_viewport_layer ? std::nullopt : std::optional<Id>{ctx.viewport_index};
|
||||||
default:
|
default:
|
||||||
throw NotImplementedException("Read attribute {}", attr);
|
throw NotImplementedException("Read attribute {}", attr);
|
||||||
}
|
}
|
||||||
|
@ -204,7 +206,11 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value) {
|
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value) {
|
||||||
ctx.OpStore(OutputAttrPointer(ctx, attr), value);
|
auto output = OutputAttrPointer(ctx, attr);
|
||||||
|
if (!output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx.OpStore(*output, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitGetAttributeIndexed(EmitContext&) {
|
void EmitGetAttributeIndexed(EmitContext&) {
|
||||||
|
|
|
@ -81,6 +81,9 @@ void SetAttribute(Info& info, IR::Attribute attribute) {
|
||||||
case IR::Attribute::ClipDistance7:
|
case IR::Attribute::ClipDistance7:
|
||||||
info.stores_clip_distance = true;
|
info.stores_clip_distance = true;
|
||||||
break;
|
break;
|
||||||
|
case IR::Attribute::ViewportIndex:
|
||||||
|
info.stores_viewport_index = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw NotImplementedException("Set attribute {}", attribute);
|
throw NotImplementedException("Set attribute {}", attribute);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct Profile {
|
||||||
bool support_fp64_signed_zero_nan_preserve{};
|
bool support_fp64_signed_zero_nan_preserve{};
|
||||||
bool support_explicit_workgroup_layout{};
|
bool support_explicit_workgroup_layout{};
|
||||||
bool support_vote{};
|
bool support_vote{};
|
||||||
|
bool support_viewport_index_layer_non_geometry{};
|
||||||
bool warp_size_potentially_larger_than_guest{};
|
bool warp_size_potentially_larger_than_guest{};
|
||||||
|
|
||||||
// FClamp is broken and OpFMax + OpFMin should be used instead
|
// FClamp is broken and OpFMax + OpFMin should be used instead
|
||||||
|
|
|
@ -82,6 +82,7 @@ struct Info {
|
||||||
bool stores_position{};
|
bool stores_position{};
|
||||||
bool stores_point_size{};
|
bool stores_point_size{};
|
||||||
bool stores_clip_distance{};
|
bool stores_clip_distance{};
|
||||||
|
bool stores_viewport_index{};
|
||||||
|
|
||||||
bool uses_fp16{};
|
bool uses_fp16{};
|
||||||
bool uses_fp64{};
|
bool uses_fp64{};
|
||||||
|
|
|
@ -631,6 +631,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::GPU& gpu_,
|
||||||
float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE,
|
float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE,
|
||||||
.support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(),
|
.support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(),
|
||||||
.support_vote = true,
|
.support_vote = true,
|
||||||
|
.support_viewport_index_layer_non_geometry = device.IsExtShaderViewportIndexLayerSupported(),
|
||||||
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
|
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(),
|
||||||
.has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR,
|
.has_broken_spirv_clamp = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR,
|
||||||
.generic_input_types{},
|
.generic_input_types{},
|
||||||
|
|
Loading…
Reference in a new issue