early-access version 2640

This commit is contained in:
pineappleEA 2022-04-03 06:41:08 +02:00
parent d15d58f409
commit f15cd058d8
8 changed files with 100 additions and 74 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 2639. This is the source code for early-access 2640.
## Legal Notice ## Legal Notice

View file

@ -191,16 +191,16 @@ private:
// This is nn::hid::detail::NpadFullKeyColorState // This is nn::hid::detail::NpadFullKeyColorState
struct NpadFullKeyColorState { struct NpadFullKeyColorState {
ColorAttribute attribute; ColorAttribute attribute{ColorAttribute::NoController};
Core::HID::NpadControllerColor fullkey; Core::HID::NpadControllerColor fullkey{};
}; };
static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size");
// This is nn::hid::detail::NpadJoyColorState // This is nn::hid::detail::NpadJoyColorState
struct NpadJoyColorState { struct NpadJoyColorState {
ColorAttribute attribute; ColorAttribute attribute{ColorAttribute::NoController};
Core::HID::NpadControllerColor left; Core::HID::NpadControllerColor left{};
Core::HID::NpadControllerColor right; Core::HID::NpadControllerColor right{};
}; };
static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size");
@ -226,11 +226,11 @@ private:
// This is nn::hid::NpadPalmaState // This is nn::hid::NpadPalmaState
// This is nn::hid::NpadSystemExtState // This is nn::hid::NpadSystemExtState
struct NPadGenericState { struct NPadGenericState {
s64_le sampling_number; s64_le sampling_number{};
Core::HID::NpadButtonState npad_buttons; Core::HID::NpadButtonState npad_buttons{};
Core::HID::AnalogStickState l_stick; Core::HID::AnalogStickState l_stick{};
Core::HID::AnalogStickState r_stick; Core::HID::AnalogStickState r_stick{};
NpadAttribute connection_status; NpadAttribute connection_status{};
INSERT_PADDING_BYTES(4); // Reserved INSERT_PADDING_BYTES(4); // Reserved
}; };
static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
@ -253,7 +253,7 @@ private:
Common::Vec3f gyro{}; Common::Vec3f gyro{};
Common::Vec3f rotation{}; Common::Vec3f rotation{};
std::array<Common::Vec3f, 3> orientation{}; std::array<Common::Vec3f, 3> orientation{};
SixAxisSensorAttribute attribute; SixAxisSensorAttribute attribute{};
INSERT_PADDING_BYTES(4); // Reserved INSERT_PADDING_BYTES(4); // Reserved
}; };
static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size"); static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
@ -325,11 +325,11 @@ private:
// This is nn::hid::detail::NfcXcdDeviceHandleStateImpl // This is nn::hid::detail::NfcXcdDeviceHandleStateImpl
struct NfcXcdDeviceHandleStateImpl { struct NfcXcdDeviceHandleStateImpl {
u64 handle; u64 handle{};
bool is_available; bool is_available{};
bool is_activated; bool is_activated{};
INSERT_PADDING_BYTES(0x6); // Reserved INSERT_PADDING_BYTES(0x6); // Reserved
u64 sampling_number; u64 sampling_number{};
}; };
static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
"NfcXcdDeviceHandleStateImpl is an invalid size"); "NfcXcdDeviceHandleStateImpl is an invalid size");
@ -366,8 +366,8 @@ private:
}; };
struct AppletFooterUi { struct AppletFooterUi {
AppletFooterUiAttributes attributes; AppletFooterUiAttributes attributes{};
AppletFooterUiType type; AppletFooterUiType type{AppletFooterUiType::None};
INSERT_PADDING_BYTES(0x5B); // Reserved INSERT_PADDING_BYTES(0x5B); // Reserved
}; };
static_assert(sizeof(AppletFooterUi) == 0x60, "AppletFooterUi is an invalid size"); static_assert(sizeof(AppletFooterUi) == 0x60, "AppletFooterUi is an invalid size");
@ -404,41 +404,41 @@ private:
// This is nn::hid::detail::NpadInternalState // This is nn::hid::detail::NpadInternalState
struct NpadInternalState { struct NpadInternalState {
Core::HID::NpadStyleTag style_tag; Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
NpadJoyAssignmentMode assignment_mode; NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual};
NpadFullKeyColorState fullkey_color; NpadFullKeyColorState fullkey_color{};
NpadJoyColorState joycon_color; NpadJoyColorState joycon_color{};
Lifo<NPadGenericState, hid_entry_count> fullkey_lifo; Lifo<NPadGenericState, hid_entry_count> fullkey_lifo{};
Lifo<NPadGenericState, hid_entry_count> handheld_lifo; Lifo<NPadGenericState, hid_entry_count> handheld_lifo{};
Lifo<NPadGenericState, hid_entry_count> joy_dual_lifo; Lifo<NPadGenericState, hid_entry_count> joy_dual_lifo{};
Lifo<NPadGenericState, hid_entry_count> joy_left_lifo; Lifo<NPadGenericState, hid_entry_count> joy_left_lifo{};
Lifo<NPadGenericState, hid_entry_count> joy_right_lifo; Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{};
Lifo<NPadGenericState, hid_entry_count> palma_lifo; Lifo<NPadGenericState, hid_entry_count> palma_lifo{};
Lifo<NPadGenericState, hid_entry_count> system_ext_lifo; Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo; Lifo<SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo; Lifo<SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo; Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo; Lifo<SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_left_lifo; Lifo<SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{};
Lifo<SixAxisSensorState, hid_entry_count> sixaxis_right_lifo; Lifo<SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{};
DeviceType device_type; DeviceType device_type{};
INSERT_PADDING_BYTES(0x4); // Reserved INSERT_PADDING_BYTES(0x4); // Reserved
NPadSystemProperties system_properties; NPadSystemProperties system_properties{};
NpadSystemButtonProperties button_properties; NpadSystemButtonProperties button_properties{};
Core::HID::NpadBatteryLevel battery_level_dual; Core::HID::NpadBatteryLevel battery_level_dual{};
Core::HID::NpadBatteryLevel battery_level_left; Core::HID::NpadBatteryLevel battery_level_left{};
Core::HID::NpadBatteryLevel battery_level_right; Core::HID::NpadBatteryLevel battery_level_right{};
union { union {
Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo{}; AppletFooterUi applet_footer{};
AppletFooterUi applet_footer; Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo;
}; };
INSERT_PADDING_BYTES(0x20); // Unknown INSERT_PADDING_BYTES(0x20); // Unknown
Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo; Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{};
NpadLarkType lark_type_l_and_main; NpadLarkType lark_type_l_and_main{};
NpadLarkType lark_type_r; NpadLarkType lark_type_r{};
NpadLuciaType lucia_type; NpadLuciaType lucia_type{};
NpadLagonType lagon_type; NpadLagonType lagon_type{};
NpadLagerType lager_type; NpadLagerType lager_type{};
// FW 13.x Investigate there is some sort of bitflag related to joycons // FW 13.x Investigate there is some sort of bitflag related to joycons
INSERT_PADDING_BYTES(0x4); INSERT_PADDING_BYTES(0x4);
INSERT_PADDING_BYTES(0xc08); // Unknown INSERT_PADDING_BYTES(0xc08); // Unknown

View file

@ -35,6 +35,15 @@ std::string_view OutputVertexIndex(EmitContext& ctx) {
return ctx.stage == Stage::TessellationControl ? "[gl_InvocationID]" : ""; return ctx.stage == Stage::TessellationControl ? "[gl_InvocationID]" : "";
} }
std::string ChooseCbuf(EmitContext& ctx, const IR::Value& binding, std::string_view index) {
if (binding.IsImmediate()) {
return fmt::format("{}_cbuf{}[{}]", ctx.stage_name, binding.U32(), index);
} else {
const auto binding_var{ctx.var_alloc.Consume(binding)};
return fmt::format("GetCbufIndirect({},{})", binding_var, index);
}
}
void GetCbuf(EmitContext& ctx, std::string_view ret, const IR::Value& binding, void GetCbuf(EmitContext& ctx, std::string_view ret, const IR::Value& binding,
const IR::Value& offset, u32 num_bits, std::string_view cast = {}, const IR::Value& offset, u32 num_bits, std::string_view cast = {},
std::string_view bit_offset = {}) { std::string_view bit_offset = {}) {
@ -55,8 +64,8 @@ void GetCbuf(EmitContext& ctx, std::string_view ret, const IR::Value& binding,
const auto swizzle{is_immediate ? fmt::format(".{}", OffsetSwizzle(offset.U32())) const auto swizzle{is_immediate ? fmt::format(".{}", OffsetSwizzle(offset.U32()))
: fmt::format("[({}>>2)%4]", offset_var)}; : fmt::format("[({}>>2)%4]", offset_var)};
const auto cbuf{fmt::format("{}_cbuf{}", ctx.stage_name, binding.U32())}; const auto cbuf{ChooseCbuf(ctx, binding, index)};
const auto cbuf_cast{fmt::format("{}({}[{}]{{}})", cast, cbuf, index)}; const auto cbuf_cast{fmt::format("{}({}{{}})", cast, cbuf)};
const auto extraction{num_bits == 32 ? cbuf_cast const auto extraction{num_bits == 32 ? cbuf_cast
: fmt::format("bitfieldExtract({},int({}),{})", cbuf_cast, : fmt::format("bitfieldExtract({},int({}),{})", cbuf_cast,
bit_offset, num_bits)}; bit_offset, num_bits)};
@ -140,9 +149,9 @@ void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
const IR::Value& offset) { const IR::Value& offset) {
const auto cbuf{fmt::format("{}_cbuf{}", ctx.stage_name, binding.U32())};
const auto cast{ctx.profile.has_gl_cbuf_ftou_bug ? "" : "ftou"}; const auto cast{ctx.profile.has_gl_cbuf_ftou_bug ? "" : "ftou"};
if (offset.IsImmediate()) { if (offset.IsImmediate()) {
const auto cbuf{fmt::format("{}_cbuf{}", ctx.stage_name, binding.U32())};
static constexpr u32 cbuf_size{0x10000}; static constexpr u32 cbuf_size{0x10000};
const u32 u32_offset{offset.U32()}; const u32 u32_offset{offset.U32()};
const s32 signed_offset{static_cast<s32>(offset.U32())}; const s32 signed_offset{static_cast<s32>(offset.U32())};
@ -162,17 +171,17 @@ void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding
return; return;
} }
const auto offset_var{ctx.var_alloc.Consume(offset)}; const auto offset_var{ctx.var_alloc.Consume(offset)};
const auto cbuf{ChooseCbuf(ctx, binding, fmt::format("{}>>4", offset_var))};
if (!ctx.profile.has_gl_component_indexing_bug) { if (!ctx.profile.has_gl_component_indexing_bug) {
ctx.AddU32x2("{}=uvec2({}({}[{}>>4][({}>>2)%4]),{}({}[({}+4)>>4][(({}+4)>>2)%4]));", inst, ctx.AddU32x2("{}=uvec2({}({}[({}>>2)%4]),{}({}[(({}+4)>>2)%4]));", inst, cast, cbuf,
cast, cbuf, offset_var, offset_var, cast, cbuf, offset_var, offset_var); offset_var, cast, cbuf, offset_var);
return; return;
} }
const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x2)}; const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x2)};
const auto cbuf_offset{fmt::format("{}>>2", offset_var)}; const auto cbuf_offset{fmt::format("{}>>2", offset_var)};
for (u32 swizzle = 0; swizzle < 4; ++swizzle) { for (u32 swizzle = 0; swizzle < 4; ++swizzle) {
ctx.Add("if(({}&3)=={}){}=uvec2({}({}[{}>>4].{}),{}({}[({}+4)>>4].{}));", cbuf_offset, ctx.Add("if(({}&3)=={}){}=uvec2({}({}.{}),{}({}.{}));", cbuf_offset, swizzle, ret, cast,
swizzle, ret, cast, cbuf, offset_var, "xyzw"[swizzle], cast, cbuf, offset_var, cbuf, "xyzw"[swizzle], cast, cbuf, "xyzw"[(swizzle + 1) % 4]);
"xyzw"[(swizzle + 1) % 4]);
} }
} }

View file

@ -359,6 +359,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
header += "layout(location=0) uniform vec4 scaling;"; header += "layout(location=0) uniform vec4 scaling;";
} }
DefineConstantBuffers(bindings); DefineConstantBuffers(bindings);
DefineConstantBufferIndirect();
DefineStorageBuffers(bindings); DefineStorageBuffers(bindings);
SetupImages(bindings); SetupImages(bindings);
SetupTextures(bindings); SetupTextures(bindings);
@ -436,6 +437,24 @@ void EmitContext::DefineConstantBuffers(Bindings& bindings) {
} }
} }
void EmitContext::DefineConstantBufferIndirect() {
if (!info.uses_cbuf_indirect) {
return;
}
header += profile.has_gl_cbuf_ftou_bug ? "uvec4 " : "vec4 ";
header += "GetCbufIndirect(uint binding, uint offset){"
"switch(binding){"
"default:";
for (const auto& desc : info.constant_buffer_descriptors) {
header +=
fmt::format("case {}:return {}_cbuf{}[offset];", desc.index, stage_name, desc.index);
}
header += "}}";
}
void EmitContext::DefineStorageBuffers(Bindings& bindings) { void EmitContext::DefineStorageBuffers(Bindings& bindings) {
if (info.storage_buffers_descriptors.empty()) { if (info.storage_buffers_descriptors.empty()) {
return; return;

View file

@ -162,6 +162,7 @@ public:
private: private:
void SetupExtensions(); void SetupExtensions();
void DefineConstantBuffers(Bindings& bindings); void DefineConstantBuffers(Bindings& bindings);
void DefineConstantBufferIndirect();
void DefineStorageBuffers(Bindings& bindings); void DefineStorageBuffers(Bindings& bindings);
void DefineGenericOutput(size_t index, u32 invocations); void DefineGenericOutput(size_t index, u32 invocations);
void DefineHelperFunctions(); void DefineHelperFunctions();

View file

@ -1043,15 +1043,15 @@ void EmitContext::DefineConstantBufferIndirectFunctions(const Info& info) {
const Id merge_label{OpLabel()}; const Id merge_label{OpLabel()};
const Id uniform_type{uniform_types.*member_ptr}; const Id uniform_type{uniform_types.*member_ptr};
std::array<Id, Info::MAX_CBUFS> buf_labels; std::array<Id, Info::MAX_INDIRECT_CBUFS> buf_labels;
std::array<Sirit::Literal, Info::MAX_CBUFS> buf_literals; std::array<Sirit::Literal, Info::MAX_INDIRECT_CBUFS> buf_literals;
for (u32 i = 0; i < Info::MAX_CBUFS; i++) { for (u32 i = 0; i < Info::MAX_INDIRECT_CBUFS; i++) {
buf_labels[i] = OpLabel(); buf_labels[i] = OpLabel();
buf_literals[i] = Sirit::Literal{i}; buf_literals[i] = Sirit::Literal{i};
} }
OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone); OpSelectionMerge(merge_label, spv::SelectionControlMask::MaskNone);
OpSwitch(binding, buf_labels[0], buf_literals, buf_labels); OpSwitch(binding, buf_labels[0], buf_literals, buf_labels);
for (u32 i = 0; i < Info::MAX_CBUFS; i++) { for (u32 i = 0; i < Info::MAX_INDIRECT_CBUFS; i++) {
AddLabel(buf_labels[i]); AddLabel(buf_labels[i]);
const Id cbuf{cbufs[i].*member_ptr}; const Id cbuf{cbufs[i].*member_ptr};
const Id access_chain{OpAccessChain(uniform_type, cbuf, u32_zero_value, offset)}; const Id access_chain{OpAccessChain(uniform_type, cbuf, u32_zero_value, offset)};
@ -1064,22 +1064,23 @@ void EmitContext::DefineConstantBufferIndirectFunctions(const Info& info) {
return func; return func;
}}; }};
IR::Type types{info.used_indirect_cbuf_types}; IR::Type types{info.used_indirect_cbuf_types};
if (True(types & IR::Type::U8)) { bool supports_aliasing = profile.support_descriptor_aliasing;
if (supports_aliasing && True(types & IR::Type::U8)) {
load_const_func_u8 = make_accessor(U8, &UniformDefinitions::U8); load_const_func_u8 = make_accessor(U8, &UniformDefinitions::U8);
} }
if (True(types & IR::Type::U16)) { if (supports_aliasing && True(types & IR::Type::U16)) {
load_const_func_u16 = make_accessor(U16, &UniformDefinitions::U16); load_const_func_u16 = make_accessor(U16, &UniformDefinitions::U16);
} }
if (True(types & IR::Type::F32)) { if (supports_aliasing && True(types & IR::Type::F32)) {
load_const_func_f32 = make_accessor(F32[1], &UniformDefinitions::F32); load_const_func_f32 = make_accessor(F32[1], &UniformDefinitions::F32);
} }
if (True(types & IR::Type::U32)) { if (supports_aliasing && True(types & IR::Type::U32)) {
load_const_func_u32 = make_accessor(U32[1], &UniformDefinitions::U32); load_const_func_u32 = make_accessor(U32[1], &UniformDefinitions::U32);
} }
if (True(types & IR::Type::U32x2)) { if (supports_aliasing && True(types & IR::Type::U32x2)) {
load_const_func_u32x2 = make_accessor(U32[2], &UniformDefinitions::U32x2); load_const_func_u32x2 = make_accessor(U32[2], &UniformDefinitions::U32x2);
} }
if (True(types & IR::Type::U32x4)) { if (!supports_aliasing || True(types & IR::Type::U32x4)) {
load_const_func_u32x4 = make_accessor(U32[4], &UniformDefinitions::U32x4); load_const_func_u32x4 = make_accessor(U32[4], &UniformDefinitions::U32x4);
} }
} }

View file

@ -32,13 +32,8 @@ void AddConstantBufferDescriptor(Info& info, u32 index, u32 count) {
void AddRegisterIndexedLdc(Info& info) { void AddRegisterIndexedLdc(Info& info) {
info.uses_cbuf_indirect = true; info.uses_cbuf_indirect = true;
// The shader can use any possible constant buffer for (u32 i = 0; i < Info::MAX_INDIRECT_CBUFS; i++) {
info.constant_buffer_mask = (1 << Info::MAX_CBUFS) - 1; AddConstantBufferDescriptor(info, i, 1);
auto& cbufs{info.constant_buffer_descriptors};
cbufs.clear();
for (u32 i = 0; i < Info::MAX_CBUFS; i++) {
cbufs.push_back(ConstantBufferDescriptor{.index = i, .count = 1});
// The shader can use any possible access size // The shader can use any possible access size
info.constant_buffer_used_sizes[i] = 0x10'000; info.constant_buffer_used_sizes[i] = 0x10'000;

View file

@ -105,6 +105,7 @@ struct ImageDescriptor {
using ImageDescriptors = boost::container::small_vector<ImageDescriptor, 4>; using ImageDescriptors = boost::container::small_vector<ImageDescriptor, 4>;
struct Info { struct Info {
static constexpr size_t MAX_INDIRECT_CBUFS{15};
static constexpr size_t MAX_CBUFS{18}; static constexpr size_t MAX_CBUFS{18};
static constexpr size_t MAX_SSBOS{32}; static constexpr size_t MAX_SSBOS{32};