From 00b81fba84ed3a084ae5a2d0a4819492cf0ceb31 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Sun, 21 Nov 2021 02:53:04 +0100 Subject: [PATCH] early-access version 2227 --- README.md | 2 +- src/common/bit_util.h | 7 + src/core/hle/service/hid/controllers/npad.cpp | 2 +- src/input_common/drivers/gc_adapter.cpp | 14 +- .../backend/glsl/emit_context.cpp | 37 ----- .../backend/glsl/emit_glsl.cpp | 2 +- .../glsl/emit_glsl_context_get_set.cpp | 64 -------- .../backend/spirv/emit_context.cpp | 143 ------------------ .../backend/spirv/emit_context.h | 15 -- .../spirv/emit_spirv_context_get_set.cpp | 31 ---- src/shader_recompiler/frontend/ir/attribute.h | 2 + .../frontend/maxwell/translate_program.cpp | 95 ++++++++++++ .../frontend/maxwell/translate_program.h | 4 + src/shader_recompiler/varying_state.h | 3 +- .../renderer_opengl/gl_shader_cache.cpp | 3 + .../renderer_opengl/gl_texture_cache.cpp | 6 +- .../renderer_vulkan/vk_pipeline_cache.cpp | 2 + .../renderer_vulkan/vk_texture_cache.cpp | 7 +- 18 files changed, 129 insertions(+), 310 deletions(-) diff --git a/README.md b/README.md index 7b61f1001..c6ed7f532 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2226. +This is the source code for early-access 2227. ## Legal Notice diff --git a/src/common/bit_util.h b/src/common/bit_util.h index 64520ca4e..eef8c1c5a 100755 --- a/src/common/bit_util.h +++ b/src/common/bit_util.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "common/common_types.h" @@ -44,4 +45,10 @@ template return static_cast(log2_f + static_cast((value ^ (1ULL << log2_f)) != 0ULL)); } +template +requires std::is_integral_v +[[nodiscard]] T NextPow2(T value) { + return static_cast(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U))); +} + } // namespace Common diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index eaec79139..4b23230e1 100755 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -345,7 +345,7 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) { constexpr btn right_button_mask = btn::A | btn::B | btn::X | btn::Y | btn::StickR | btn::R | btn::ZR | btn::Plus | btn::StickRLeft | btn::StickRUp | btn::StickRRight | btn::StickRDown; - pad_entry.npad_buttons.raw |= button_state.raw & right_button_mask; + pad_entry.npad_buttons.raw = button_state.raw & right_button_mask; pad_entry.r_stick = stick_state.right; } diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp index d775a1599..a1b9b6d98 100755 --- a/src/input_common/drivers/gc_adapter.cpp +++ b/src/input_common/drivers/gc_adapter.cpp @@ -272,13 +272,6 @@ bool GCAdapter::CheckDeviceAccess() { } } - // This fixes payload problems from offbrand GCAdapters - const s32 control_transfer_error = - libusb_control_transfer(usb_adapter_handle->get(), 0x21, 11, 0x0001, 0, nullptr, 0, 1000); - if (control_transfer_error < 0) { - LOG_ERROR(Input, "libusb_control_transfer failed with error= {}", control_transfer_error); - } - if (kernel_driver_error && kernel_driver_error != LIBUSB_ERROR_NOT_SUPPORTED) { usb_adapter_handle = nullptr; return false; @@ -291,6 +284,13 @@ bool GCAdapter::CheckDeviceAccess() { return false; } + // This fixes payload problems from offbrand GCAdapters + const s32 control_transfer_error = + libusb_control_transfer(usb_adapter_handle->get(), 0x21, 11, 0x0001, 0, nullptr, 0, 1000); + if (control_transfer_error < 0) { + LOG_ERROR(Input, "libusb_control_transfer failed with error= {}", control_transfer_error); + } + return true; } diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 97bd59302..f79ab798e 100755 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -211,27 +211,6 @@ std::string_view OutputPrimitive(OutputTopology topology) { throw InvalidArgument("Invalid output topology {}", topology); } -void SetupLegacyOutPerVertex(EmitContext& ctx, std::string& header) { - if (!ctx.info.stores.Legacy()) { - return; - } - if (ctx.info.stores.FixedFunctionTexture()) { - header += "vec4 gl_TexCoord[8];"; - } - if (ctx.info.stores.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { - header += "vec4 gl_FrontColor;"; - } - if (ctx.info.stores.AnyComponent(IR::Attribute::ColorFrontSpecularR)) { - header += "vec4 gl_FrontSecondaryColor;"; - } - if (ctx.info.stores.AnyComponent(IR::Attribute::ColorBackDiffuseR)) { - header += "vec4 gl_BackColor;"; - } - if (ctx.info.stores.AnyComponent(IR::Attribute::ColorBackSpecularR)) { - header += "vec4 gl_BackSecondaryColor;"; - } -} - void SetupOutPerVertex(EmitContext& ctx, std::string& header) { if (!StoresPerVertexAttributes(ctx.stage)) { return; @@ -250,7 +229,6 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { ctx.profile.support_viewport_index_layer_non_geometry && ctx.stage != Stage::Geometry) { header += "int gl_ViewportIndex;"; } - SetupLegacyOutPerVertex(ctx, header); header += "};"; if (ctx.info.stores[IR::Attribute::ViewportIndex] && ctx.stage == Stage::Geometry) { header += "out int gl_ViewportIndex;"; @@ -283,20 +261,6 @@ void SetupInPerVertex(EmitContext& ctx, std::string& header) { header += "}gl_in[gl_MaxPatchVertices];"; } -void SetupLegacyInPerFragment(EmitContext& ctx, std::string& header) { - if (!ctx.info.loads.Legacy()) { - return; - } - header += "in gl_PerFragment{"; - if (ctx.info.loads.FixedFunctionTexture()) { - header += "vec4 gl_TexCoord[8];"; - } - if (ctx.info.loads.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { - header += "vec4 gl_Color;"; - } - header += "};"; -} - } // Anonymous namespace EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, @@ -361,7 +325,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile } SetupOutPerVertex(*this, header); SetupInPerVertex(*this, header); - SetupLegacyInPerFragment(*this, header); for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { if (!info.loads.Generic(index) || !runtime_info.previous_stage_stores.Generic(index)) { diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp index 8a430d573..bc5e7ffe9 100755 --- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp @@ -176,7 +176,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { } std::string GlslVersionSpecifier(const EmitContext& ctx) { - if (ctx.uses_y_direction || ctx.info.stores.Legacy() || ctx.info.loads.Legacy()) { + if (ctx.uses_y_direction) { return " compatibility"; } return ""; diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index 4c26f3829..8b590ef36 100755 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp @@ -98,10 +98,6 @@ void GetCbuf16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, const GetCbuf(ctx, ret, binding, offset, 16, cast, bit_offset); } } - -u32 TexCoordIndex(IR::Attribute attr) { - return (static_cast(attr) - static_cast(IR::Attribute::FixedFncTexture0S)) / 4; -} } // Anonymous namespace void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, @@ -190,18 +186,6 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle); return; } - // GLSL only exposes 8 legacy texcoords - if (attr >= IR::Attribute::FixedFncTexture8S && attr <= IR::Attribute::FixedFncTexture9Q) { - LOG_WARNING(Shader_GLSL, "GLSL does not allow access to gl_TexCoord[{}]", - TexCoordIndex(attr)); - ctx.AddF32("{}=0.f;", inst); - return; - } - if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture7Q) { - const u32 index{TexCoordIndex(attr)}; - ctx.AddF32("{}=gl_TexCoord[{}].{};", inst, index, swizzle); - return; - } switch (attr) { case IR::Attribute::PrimitiveId: ctx.AddF32("{}=itof(gl_PrimitiveID);", inst); @@ -215,16 +199,6 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, ctx.AddF32("{}={}{}.{};", inst, input_decorator, ctx.position_name, swizzle); break; } - case IR::Attribute::ColorFrontDiffuseR: - case IR::Attribute::ColorFrontDiffuseG: - case IR::Attribute::ColorFrontDiffuseB: - case IR::Attribute::ColorFrontDiffuseA: - if (ctx.stage == Stage::Fragment) { - ctx.AddF32("{}=gl_Color.{};", inst, swizzle); - } else { - ctx.AddF32("{}=gl_FrontColor.{};", inst, swizzle); - } - break; case IR::Attribute::PointSpriteS: case IR::Attribute::PointSpriteT: ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle); @@ -264,17 +238,6 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val } const u32 element{static_cast(attr) % 4}; const char swizzle{"xyzw"[element]}; - // GLSL only exposes 8 legacy texcoords - if (attr >= IR::Attribute::FixedFncTexture8S && attr <= IR::Attribute::FixedFncTexture9Q) { - LOG_WARNING(Shader_GLSL, "GLSL does not allow access to gl_TexCoord[{}]", - TexCoordIndex(attr)); - return; - } - if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture7Q) { - const u32 index{TexCoordIndex(attr)}; - ctx.Add("gl_TexCoord[{}].{}={};", index, swizzle, value); - return; - } switch (attr) { case IR::Attribute::Layer: if (ctx.stage != Stage::Geometry && @@ -312,33 +275,6 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val case IR::Attribute::PositionW: ctx.Add("gl_Position.{}={};", swizzle, value); break; - case IR::Attribute::ColorFrontDiffuseR: - case IR::Attribute::ColorFrontDiffuseG: - case IR::Attribute::ColorFrontDiffuseB: - case IR::Attribute::ColorFrontDiffuseA: - ctx.Add("gl_FrontColor.{}={};", swizzle, value); - break; - case IR::Attribute::ColorFrontSpecularR: - case IR::Attribute::ColorFrontSpecularG: - case IR::Attribute::ColorFrontSpecularB: - case IR::Attribute::ColorFrontSpecularA: - ctx.Add("gl_FrontSecondaryColor.{}={};", swizzle, value); - break; - case IR::Attribute::ColorBackDiffuseR: - case IR::Attribute::ColorBackDiffuseG: - case IR::Attribute::ColorBackDiffuseB: - case IR::Attribute::ColorBackDiffuseA: - ctx.Add("gl_BackColor.{}={};", swizzle, value); - break; - case IR::Attribute::ColorBackSpecularR: - case IR::Attribute::ColorBackSpecularG: - case IR::Attribute::ColorBackSpecularB: - case IR::Attribute::ColorBackSpecularA: - ctx.Add("gl_BackSecondaryColor.{}={};", swizzle, value); - break; - case IR::Attribute::FogCoordinate: - ctx.Add("gl_FogFragCoord={};", value); - break; case IR::Attribute::ClipDistance0: case IR::Attribute::ClipDistance1: case IR::Attribute::ClipDistance2: diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 723455462..937d53321 100755 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp @@ -18,8 +18,6 @@ namespace Shader::Backend::SPIRV { namespace { -constexpr size_t NUM_FIXEDFNCTEXTURE = 10; - enum class Operation { Increment, Decrement, @@ -432,34 +430,6 @@ Id DescType(EmitContext& ctx, Id sampled_type, Id pointer_type, u32 count) { return pointer_type; } } - -size_t FindAndSetNextUnusedLocation(std::bitset& used_locations, - size_t& start_offset) { - for (size_t location = start_offset; location < used_locations.size(); ++location) { - if (!used_locations.test(location)) { - start_offset = location; - used_locations.set(location); - return location; - } - } - throw RuntimeError("Unable to get an unused location for legacy attribute"); -} - -Id DefineLegacyInput(EmitContext& ctx, std::bitset& used_locations, - size_t& start_offset) { - const Id id{DefineInput(ctx, ctx.F32[4], true)}; - const size_t location = FindAndSetNextUnusedLocation(used_locations, start_offset); - ctx.Decorate(id, spv::Decoration::Location, location); - return id; -} - -Id DefineLegacyOutput(EmitContext& ctx, std::bitset& used_locations, - size_t& start_offset, std::optional invocations) { - const Id id{DefineOutput(ctx, ctx.F32[4], invocations)}; - const size_t location = FindAndSetNextUnusedLocation(used_locations, start_offset); - ctx.Decorate(id, spv::Decoration::Location, location); - return id; -} } // Anonymous namespace void VectorTypes::Define(Sirit::Module& sirit_ctx, Id base_type, std::string_view name) { @@ -543,64 +513,6 @@ Id EmitContext::BitOffset16(const IR::Value& offset) { return OpBitwiseAnd(U32[1], OpShiftLeftLogical(U32[1], Def(offset), Const(3u)), Const(16u)); } -Id EmitContext::InputLegacyAttribute(IR::Attribute attribute) { - if (attribute >= IR::Attribute::ColorFrontDiffuseR && - attribute <= IR::Attribute::ColorFrontDiffuseA) { - return input_front_color; - } - if (attribute >= IR::Attribute::ColorFrontSpecularR && - attribute <= IR::Attribute::ColorFrontSpecularA) { - return input_front_secondary_color; - } - if (attribute >= IR::Attribute::ColorBackDiffuseR && - attribute <= IR::Attribute::ColorBackDiffuseA) { - return input_back_color; - } - if (attribute >= IR::Attribute::ColorBackSpecularR && - attribute <= IR::Attribute::ColorBackSpecularA) { - return input_back_secondary_color; - } - if (attribute == IR::Attribute::FogCoordinate) { - return input_fog_frag_coord; - } - if (attribute >= IR::Attribute::FixedFncTexture0S && - attribute <= IR::Attribute::FixedFncTexture9Q) { - u32 index = - (static_cast(attribute) - static_cast(IR::Attribute::FixedFncTexture0S)) / 4; - return input_fixed_fnc_textures[index]; - } - throw InvalidArgument("Attribute is not legacy attribute {}", attribute); -} - -Id EmitContext::OutputLegacyAttribute(IR::Attribute attribute) { - if (attribute >= IR::Attribute::ColorFrontDiffuseR && - attribute <= IR::Attribute::ColorFrontDiffuseA) { - return output_front_color; - } - if (attribute >= IR::Attribute::ColorFrontSpecularR && - attribute <= IR::Attribute::ColorFrontSpecularA) { - return output_front_secondary_color; - } - if (attribute >= IR::Attribute::ColorBackDiffuseR && - attribute <= IR::Attribute::ColorBackDiffuseA) { - return output_back_color; - } - if (attribute >= IR::Attribute::ColorBackSpecularR && - attribute <= IR::Attribute::ColorBackSpecularA) { - return output_back_secondary_color; - } - if (attribute == IR::Attribute::FogCoordinate) { - return output_fog_frag_coord; - } - if (attribute >= IR::Attribute::FixedFncTexture0S && - attribute <= IR::Attribute::FixedFncTexture9Q) { - u32 index = - (static_cast(attribute) - static_cast(IR::Attribute::FixedFncTexture0S)) / 4; - return output_fixed_fnc_textures[index]; - } - throw InvalidArgument("Attribute is not legacy attribute {}", attribute); -} - void EmitContext::DefineCommonTypes(const Info& info) { void_id = TypeVoid(); @@ -1389,7 +1301,6 @@ void EmitContext::DefineInputs(const IR::Program& program) { loads[IR::Attribute::TessellationEvaluationPointV]) { tess_coord = DefineInput(*this, F32[3], false, spv::BuiltIn::TessCoord); } - std::bitset used_locations{}; for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { const AttributeType input_type{runtime_info.generic_input_types[index]}; if (!runtime_info.previous_stage_stores.Generic(index)) { @@ -1401,7 +1312,6 @@ void EmitContext::DefineInputs(const IR::Program& program) { if (input_type == AttributeType::Disabled) { continue; } - used_locations.set(index); const Id type{GetAttributeType(*this, input_type)}; const Id id{DefineInput(*this, type, true)}; Decorate(id, spv::Decoration::Location, static_cast(index)); @@ -1427,30 +1337,6 @@ void EmitContext::DefineInputs(const IR::Program& program) { break; } } - size_t previous_unused_location = 0; - if (loads.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { - input_front_color = DefineLegacyInput(*this, used_locations, previous_unused_location); - } - if (loads.AnyComponent(IR::Attribute::ColorFrontSpecularR)) { - input_front_secondary_color = - DefineLegacyInput(*this, used_locations, previous_unused_location); - } - if (loads.AnyComponent(IR::Attribute::ColorBackDiffuseR)) { - input_back_color = DefineLegacyInput(*this, used_locations, previous_unused_location); - } - if (loads.AnyComponent(IR::Attribute::ColorBackSpecularR)) { - input_back_secondary_color = - DefineLegacyInput(*this, used_locations, previous_unused_location); - } - if (loads.AnyComponent(IR::Attribute::FogCoordinate)) { - input_fog_frag_coord = DefineLegacyInput(*this, used_locations, previous_unused_location); - } - for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { - if (loads.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { - input_fixed_fnc_textures[index] = - DefineLegacyInput(*this, used_locations, previous_unused_location); - } - } if (stage == Stage::TessellationEval) { for (size_t index = 0; index < info.uses_patches.size(); ++index) { if (!info.uses_patches[index]) { @@ -1501,38 +1387,9 @@ void EmitContext::DefineOutputs(const IR::Program& program) { viewport_mask = DefineOutput(*this, TypeArray(U32[1], Const(1u)), std::nullopt, spv::BuiltIn::ViewportMaskNV); } - std::bitset used_locations{}; for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { if (info.stores.Generic(index)) { DefineGenericOutput(*this, index, invocations); - used_locations.set(index); - } - } - size_t previous_unused_location = 0; - if (info.stores.AnyComponent(IR::Attribute::ColorFrontDiffuseR)) { - output_front_color = - DefineLegacyOutput(*this, used_locations, previous_unused_location, invocations); - } - if (info.stores.AnyComponent(IR::Attribute::ColorFrontSpecularR)) { - output_front_secondary_color = - DefineLegacyOutput(*this, used_locations, previous_unused_location, invocations); - } - if (info.stores.AnyComponent(IR::Attribute::ColorBackDiffuseR)) { - output_back_color = - DefineLegacyOutput(*this, used_locations, previous_unused_location, invocations); - } - if (info.stores.AnyComponent(IR::Attribute::ColorBackSpecularR)) { - output_back_secondary_color = - DefineLegacyOutput(*this, used_locations, previous_unused_location, invocations); - } - if (info.stores.AnyComponent(IR::Attribute::FogCoordinate)) { - output_fog_frag_coord = - DefineLegacyOutput(*this, used_locations, previous_unused_location, invocations); - } - for (size_t index = 0; index < NUM_FIXEDFNCTEXTURE; ++index) { - if (info.stores.AnyComponent(IR::Attribute::FixedFncTexture0S + index * 4)) { - output_fixed_fnc_textures[index] = - DefineLegacyOutput(*this, used_locations, previous_unused_location, invocations); } } switch (stage) { diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 63f8185d9..f87138f7e 100755 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h @@ -113,9 +113,6 @@ public: [[nodiscard]] Id BitOffset8(const IR::Value& offset); [[nodiscard]] Id BitOffset16(const IR::Value& offset); - Id InputLegacyAttribute(IR::Attribute attribute); - Id OutputLegacyAttribute(IR::Attribute attribute); - Id Const(u32 value) { return Constant(U32[1], value); } @@ -281,22 +278,10 @@ public: Id write_global_func_u32x4{}; Id input_position{}; - Id input_front_color{}; - Id input_front_secondary_color{}; - Id input_back_color{}; - Id input_back_secondary_color{}; - Id input_fog_frag_coord{}; - std::array input_fixed_fnc_textures{}; std::array input_generics{}; Id output_point_size{}; Id output_position{}; - Id output_front_color{}; - Id output_front_secondary_color{}; - Id output_back_color{}; - Id output_back_secondary_color{}; - Id output_fog_frag_coord{}; - std::array output_fixed_fnc_textures{}; std::array, 32> output_generics{}; Id output_tess_level_outer{}; diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index bac683ae1..3adc01b38 100755 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -43,14 +43,6 @@ Id AttrPointer(EmitContext& ctx, Id pointer_type, Id vertex, Id base, Args&&... } } -bool IsLegacyAttribute(IR::Attribute attribute) { - return (attribute >= IR::Attribute::ColorFrontDiffuseR && - attribute <= IR::Attribute::ColorBackSpecularA) || - attribute == IR::Attribute::FogCoordinate || - (attribute >= IR::Attribute::FixedFncTexture0S && - attribute <= IR::Attribute::FixedFncTexture9Q); -} - template Id OutputAccessChain(EmitContext& ctx, Id result_type, Id base, Args&&... args) { if (ctx.stage == Stage::TessellationControl) { @@ -82,17 +74,6 @@ std::optional OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { return OutputAccessChain(ctx, ctx.output_f32, info.id, index_id); } } - if (IsLegacyAttribute(attr)) { - if (attr == IR::Attribute::FogCoordinate) { - return OutputAccessChain(ctx, ctx.output_f32, ctx.OutputLegacyAttribute(attr), - ctx.Const(0u)); - } else { - const u32 element{static_cast(attr) % 4}; - const Id element_id{ctx.Const(element)}; - return OutputAccessChain(ctx, ctx.output_f32, ctx.OutputLegacyAttribute(attr), - element_id); - } - } switch (attr) { case IR::Attribute::PointSize: return ctx.output_point_size; @@ -326,18 +307,6 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) { const Id value{ctx.OpLoad(type->id, pointer)}; return type->needs_cast ? ctx.OpBitcast(ctx.F32[1], value) : value; } - if (IsLegacyAttribute(attr)) { - if (attr == IR::Attribute::FogCoordinate) { - const Id attr_ptr{AttrPointer(ctx, ctx.input_f32, vertex, - ctx.InputLegacyAttribute(attr), ctx.Const(0u))}; - return ctx.OpLoad(ctx.F32[1], attr_ptr); - } else { - const Id element_id{ctx.Const(element)}; - const Id attr_ptr{AttrPointer(ctx, ctx.input_f32, vertex, - ctx.InputLegacyAttribute(attr), element_id)}; - return ctx.OpLoad(ctx.F32[1], attr_ptr); - } - } switch (attr) { case IR::Attribute::PrimitiveId: return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.primitive_id)); diff --git a/src/shader_recompiler/frontend/ir/attribute.h b/src/shader_recompiler/frontend/ir/attribute.h index ca1199494..3bbd38a03 100755 --- a/src/shader_recompiler/frontend/ir/attribute.h +++ b/src/shader_recompiler/frontend/ir/attribute.h @@ -224,6 +224,8 @@ enum class Attribute : u64 { constexpr size_t NUM_GENERICS = 32; +constexpr size_t NUM_FIXEDFNCTEXTURE = 10; + [[nodiscard]] bool IsGeneric(Attribute attribute) noexcept; [[nodiscard]] u32 GenericAttributeIndex(Attribute attribute); diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp index 267ebe4af..248ad3ced 100755 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "common/settings.h" #include "shader_recompiler/exception.h" @@ -127,6 +128,42 @@ void AddNVNStorageBuffers(IR::Program& program) { }); } } + +bool IsLegacyAttribute(IR::Attribute attribute) { + return (attribute >= IR::Attribute::ColorFrontDiffuseR && + attribute <= IR::Attribute::ColorBackSpecularA) || + attribute == IR::Attribute::FogCoordinate || + (attribute >= IR::Attribute::FixedFncTexture0S && + attribute <= IR::Attribute::FixedFncTexture9Q); +} + +std::map GenerateLegacyToGenericMappings( + const VaryingState& state, std::queue ununsed_generics) { + std::map mapping; + for (size_t index = 0; index < 4; ++index) { + auto attr = IR::Attribute::ColorFrontDiffuseR + index * 4; + if (state.AnyComponent(attr)) { + for (size_t i = 0; i < 4; ++i) { + mapping.insert({attr + i, ununsed_generics.front() + i}); + } + ununsed_generics.pop(); + } + } + if (state[IR::Attribute::FogCoordinate]) { + mapping.insert({IR::Attribute::FogCoordinate, ununsed_generics.front()}); + ununsed_generics.pop(); + } + for (size_t index = 0; index < IR::NUM_FIXEDFNCTEXTURE; ++index) { + auto attr = IR::Attribute::FixedFncTexture0S + index * 4; + if (state.AnyComponent(attr)) { + for (size_t i = 0; i < 4; ++i) { + mapping.insert({attr + i, ununsed_generics.front() + i}); + } + ununsed_generics.pop(); + } + } + return mapping; +} } // Anonymous namespace IR::Program TranslateProgram(ObjectPool& inst_pool, ObjectPool& block_pool, @@ -226,4 +263,62 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b return result; } +void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& runtime_info) { + auto& stores = program.info.stores; + if (stores.Legacy()) { + std::queue ununsed_output_generics{}; + for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { + if (!stores.Generic(index)) { + ununsed_output_generics.push(IR::Attribute::Generic0X + index * 4); + } + } + auto mappings = GenerateLegacyToGenericMappings(stores, ununsed_output_generics); + for (IR::Block* const block : program.post_order_blocks) { + for (IR::Inst& inst : block->Instructions()) { + switch (inst.GetOpcode()) { + case IR::Opcode::SetAttribute: { + const auto attr = inst.Arg(0).Attribute(); + if (IsLegacyAttribute(attr)) { + stores.Set(mappings[attr], true); + inst.SetArg(0, Shader::IR::Value(mappings[attr])); + } + break; + } + default: + break; + } + } + } + } + + auto& loads = program.info.loads; + if (loads.Legacy()) { + std::queue ununsed_input_generics{}; + for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { + const AttributeType input_type{runtime_info.generic_input_types[index]}; + if (!runtime_info.previous_stage_stores.Generic(index) || !loads.Generic(index) || + input_type == AttributeType::Disabled) { + ununsed_input_generics.push(IR::Attribute::Generic0X + index * 4); + } + } + auto mappings = GenerateLegacyToGenericMappings(loads, ununsed_input_generics); + for (IR::Block* const block : program.post_order_blocks) { + for (IR::Inst& inst : block->Instructions()) { + switch (inst.GetOpcode()) { + case IR::Opcode::GetAttribute: { + const auto attr = inst.Arg(0).Attribute(); + if (IsLegacyAttribute(attr)) { + loads.Set(mappings[attr], true); + inst.SetArg(0, Shader::IR::Value(mappings[attr])); + } + break; + } + default: + break; + } + } + } + } +} + } // namespace Shader::Maxwell diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.h b/src/shader_recompiler/frontend/maxwell/translate_program.h index a84814811..cd535f20d 100755 --- a/src/shader_recompiler/frontend/maxwell/translate_program.h +++ b/src/shader_recompiler/frontend/maxwell/translate_program.h @@ -10,6 +10,7 @@ #include "shader_recompiler/frontend/maxwell/control_flow.h" #include "shader_recompiler/host_translate_info.h" #include "shader_recompiler/object_pool.h" +#include "shader_recompiler/runtime_info.h" namespace Shader::Maxwell { @@ -20,4 +21,7 @@ namespace Shader::Maxwell { [[nodiscard]] IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b, Environment& env_vertex_b); +[[nodiscard]] void ConvertLegacyToGeneric(IR::Program& program, + const Shader::RuntimeInfo& runtime_info); + } // namespace Shader::Maxwell diff --git a/src/shader_recompiler/varying_state.h b/src/shader_recompiler/varying_state.h index 9d7b24a76..bc4f273c8 100755 --- a/src/shader_recompiler/varying_state.h +++ b/src/shader_recompiler/varying_state.h @@ -53,7 +53,8 @@ struct VaryingState { return AnyComponent(IR::Attribute::ColorFrontDiffuseR) || AnyComponent(IR::Attribute::ColorFrontSpecularR) || AnyComponent(IR::Attribute::ColorBackDiffuseR) || - AnyComponent(IR::Attribute::ColorBackSpecularR) || FixedFunctionTexture(); + AnyComponent(IR::Attribute::ColorBackSpecularR) || FixedFunctionTexture() || + mask[static_cast(IR::Attribute::FogCoordinate)]; } [[nodiscard]] bool FixedFunctionTexture() const noexcept { diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 4e86addb5..c75d3f77b 100755 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -42,6 +42,7 @@ namespace { using Shader::Backend::GLASM::EmitGLASM; using Shader::Backend::GLSL::EmitGLSL; using Shader::Backend::SPIRV::EmitSPIRV; +using Shader::Maxwell::ConvertLegacyToGeneric; using Shader::Maxwell::MergeDualVertexPrograms; using Shader::Maxwell::TranslateProgram; using VideoCommon::ComputeEnvironment; @@ -467,12 +468,14 @@ std::unique_ptr ShaderCache::CreateGraphicsPipeline( MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)}; switch (device.GetShaderBackend()) { case Settings::ShaderBackend::GLSL: + ConvertLegacyToGeneric(program, runtime_info); sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); break; case Settings::ShaderBackend::GLASM: sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); break; case Settings::ShaderBackend::SPIRV: + ConvertLegacyToGeneric(program, runtime_info); sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding); break; } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 406e8086d..14e6522f2 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -9,6 +9,7 @@ #include +#include "common/bit_util.h" #include "common/literals.h" #include "common/settings.h" #include "video_core/renderer_opengl/gl_device.h" @@ -398,9 +399,6 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form return GL_R32UI; } -[[nodiscard]] u32 NextPow2(u32 value) { - return 1U << (32U - std::countl_zero(value - 1U)); -} } // Anonymous namespace ImageBufferMap::~ImageBufferMap() { @@ -1333,7 +1331,7 @@ void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image, const u32 copy_size = region.width * region.height * region.depth * img_bpp; if (pbo_size < copy_size) { intermediate_pbo.Create(); - pbo_size = NextPow2(copy_size); + pbo_size = Common::NextPow2(copy_size); glNamedBufferData(intermediate_pbo.handle, pbo_size, nullptr, GL_STREAM_COPY); } // Copy from source to PBO diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 7b7e913ad..a633b73e5 100755 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -48,6 +48,7 @@ MICROPROFILE_DECLARE(Vulkan_PipelineCache); namespace { using Shader::Backend::SPIRV::EmitSPIRV; +using Shader::Maxwell::ConvertLegacyToGeneric; using Shader::Maxwell::MergeDualVertexPrograms; using Shader::Maxwell::TranslateProgram; using VideoCommon::ComputeEnvironment; @@ -546,6 +547,7 @@ std::unique_ptr PipelineCache::CreateGraphicsPipeline( infos[stage_index] = &program.info; const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage)}; + ConvertLegacyToGeneric(program, runtime_info); const std::vector code{EmitSPIRV(profile, runtime_info, program, binding)}; device.SaveShader(code); modules[stage_index] = BuildShader(device, code); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index e5637db05..3964424af 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -8,6 +8,7 @@ #include #include "common/bit_cast.h" +#include "common/bit_util.h" #include "common/settings.h" #include "video_core/engines/fermi_2d.h" @@ -780,16 +781,12 @@ bool TextureCacheRuntime::ShouldReinterpret(Image& dst, Image& src) { return false; } -[[nodiscard]] size_t NextPow2(size_t value) { - return static_cast(1ULL << ((8U * sizeof(size_t)) - std::countl_zero(value - 1U))); -} - VkBuffer TextureCacheRuntime::GetTemporaryBuffer(size_t needed_size) { const auto level = (8 * sizeof(size_t)) - std::countl_zero(needed_size - 1ULL); if (buffer_commits[level]) { return *buffers[level]; } - const auto new_size = NextPow2(needed_size); + const auto new_size = Common::NextPow2(needed_size); VkBufferUsageFlags flags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;