Compare commits

..

13 Commits

Author SHA1 Message Date
Liam
36b70dec05 kernel: avoid usage of bit_cast 2023-02-10 09:13:58 -05:00
liamwhite
c5743d5499 Merge pull request #9736 from Kelebek1/dynamic_vertex_attribs
Remove fake vertex bindings when dynamic state is enabled
2023-02-09 22:14:55 -05:00
liamwhite
cbb289fbee Merge pull request #9750 from ameerj/glsl-sample-id-mask
glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
2023-02-09 22:14:47 -05:00
liamwhite
c0b36c2d26 Merge pull request #9758 from german77/multi_audio
audio: cubeb: Fix yuzu crashing when it test for latency
2023-02-09 22:14:33 -05:00
Narr the Reg
7c0dcea96c audio: cubeb: Fix yuzu crashing when it test for latency 2023-02-09 19:38:03 -06:00
Matías Locatti
7bad3a7e5e Merge pull request #9749 from ameerj/pr9559-partial-revert
buffer_base: Partially revert changes from #9559
2023-02-09 17:53:45 -03:00
ameerj
eb9f16dce4 buffer_base: Partially revert changes from #9559
This fixes a regression where Yoshi's Crafted World (and potentially other titles) would enter an infinite loop when GPU Accuracy was set to "Normal"
2023-02-08 19:37:23 -05:00
ameerj
04139cb3ed glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
These built-ins seem to be available without needing to be declared for fragment shaders, similar i.e. to gl_FragDepth
2023-02-08 19:34:39 -05:00
liamwhite
f6477b91f9 Merge pull request #9747 from german77/SetSupportedNpadIdTypes
service: hid: Return error if arguments of SetSupportedNpadIdType is invalid
2023-02-08 10:09:26 -05:00
Narr the Reg
c27006e99d service: hid: Return error if arguments of SetSupportedNpadIdType is invalid 2023-02-07 21:11:39 -06:00
Mai
f3b532d091 Merge pull request #9739 from liamwhite/old-gcc-fix
kernel: fix compilation with older gcc
2023-02-07 22:10:35 -05:00
Liam
82c2a3da9f kernel: fix compilation with older gcc 2023-02-06 13:14:27 -05:00
Kelebek1
8ae2a664d2 Remove fake vertex bindings when dynamic state is enabled 2023-02-05 22:28:03 +00:00
15 changed files with 66 additions and 52 deletions

View File

@@ -302,11 +302,21 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
std::vector<std::string> device_list;
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
return {};
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT};
cubeb_device_collection collection;
if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) {
@@ -329,12 +339,22 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
u32 GetCubebLatency() {
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
// Return a large latency so we choose SDL instead.
return 10000u;
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
cubeb_stream_params params{};
params.rate = TargetSampleRate;
params.channels = 2;

View File

@@ -203,23 +203,23 @@ Result KCapabilities::ProcessMapRegionCapability(const u32 cap, F f) {
Result KCapabilities::MapRegion_(const u32 cap, KPageTable* page_table) {
// Map each region into the process's page table.
R_RETURN(ProcessMapRegionCapability(
return ProcessMapRegionCapability(
cap, [](KMemoryRegionType region_type, KMemoryPermission perm) -> Result {
// R_RETURN(page_table->MapRegion(region_type, perm));
UNIMPLEMENTED();
R_SUCCEED();
}));
});
}
Result KCapabilities::CheckMapRegion(KernelCore& kernel, const u32 cap) {
// Check that each region has a physical backing store.
R_RETURN(ProcessMapRegionCapability(
return ProcessMapRegionCapability(
cap, [&](KMemoryRegionType region_type, KMemoryPermission perm) -> Result {
R_UNLESS(kernel.MemoryLayout().GetPhysicalMemoryRegionTree().FindFirstDerived(
region_type) != nullptr,
ResultOutOfRange);
R_SUCCEED();
}));
});
}
Result KCapabilities::SetInterruptPairCapability(const u32 cap) {

View File

@@ -3,6 +3,7 @@
#pragma once
#include <condition_variable>
#include <cstddef>
#include <memory>
#include <mutex>

View File

@@ -35,11 +35,11 @@ constexpr inline u32 EncodeKernelVersion(u32 major, u32 minor) {
}
constexpr inline u32 GetKernelMajorVersion(u32 encoded) {
return std::bit_cast<decltype(KernelVersion::major_version)>(encoded).Value();
return decltype(KernelVersion::major_version)::ExtractValue(encoded);
}
constexpr inline u32 GetKernelMinorVersion(u32 encoded) {
return std::bit_cast<decltype(KernelVersion::minor_version)>(encoded).Value();
return decltype(KernelVersion::minor_version)::ExtractValue(encoded);
}
// Nintendo doesn't support programs targeting SVC versions < 3.0.

View File

@@ -758,12 +758,20 @@ Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const {
return hid_core.GetSupportedStyleTag();
}
void Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
Result Controller_NPad::SetSupportedNpadIdTypes(std::span<const u8> data) {
constexpr std::size_t max_number_npad_ids = 0xa;
const auto length = data.size();
ASSERT(length > 0 && (length % sizeof(u32)) == 0);
const std::size_t elements = length / sizeof(u32);
if (elements > max_number_npad_ids) {
return InvalidArraySize;
}
supported_npad_id_types.clear();
supported_npad_id_types.resize(length / sizeof(u32));
supported_npad_id_types.resize(elements);
std::memcpy(supported_npad_id_types.data(), data.data(), length);
return ResultSuccess;
}
void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {

View File

@@ -96,7 +96,7 @@ public:
void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
Core::HID::NpadStyleTag GetSupportedStyleSet() const;
void SetSupportedNpadIdTypes(std::span<const u8> data);
Result SetSupportedNpadIdTypes(std::span<const u8> data);
void GetSupportedNpadIdTypes(u32* data, std::size_t max_length);
std::size_t GetSupportedNpadIdTypesSize() const;

View File

@@ -18,6 +18,7 @@ constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};
constexpr Result NpadIsSameType{ErrorModule::HID, 602};
constexpr Result InvalidNpadId{ErrorModule::HID, 709};
constexpr Result NpadNotConnected{ErrorModule::HID, 710};
constexpr Result InvalidArraySize{ErrorModule::HID, 715};
constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
} // namespace Service::HID

View File

@@ -1025,13 +1025,13 @@ void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.SetSupportedNpadIdTypes(ctx.ReadBuffer());
const auto result = applet_resource->GetController<Controller_NPad>(HidController::NPad)
.SetSupportedNpadIdTypes(ctx.ReadBuffer());
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) {

View File

@@ -310,12 +310,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
if (runtime_info.force_early_z) {
header += "layout(early_fragment_tests)in;";
}
if (info.uses_sample_id) {
header += "in int gl_SampleID;";
}
if (info.stores_sample_mask) {
header += "out int gl_SampleMask[];";
}
break;
case Stage::Compute:
stage_name = "cs";

View File

@@ -538,7 +538,7 @@ TEST_CASE("BufferBase: Cached write downloads") {
int num = 0;
buffer.ForEachDownloadRangeAndClear(c, WORD, [&](u64 offset, u64 size) { ++num; });
buffer.ForEachUploadRange(c, WORD, [&](u64 offset, u64 size) { ++num; });
REQUIRE(num == 1);
REQUIRE(num == 0);
REQUIRE(!buffer.IsRegionCpuModified(c + PAGE, PAGE));
REQUIRE(!buffer.IsRegionGpuModified(c + PAGE, PAGE));
buffer.FlushCachedWrites();

View File

@@ -430,7 +430,7 @@ private:
if (query_begin >= SizeBytes() || size < 0) {
return;
}
[[maybe_unused]] u64* const untracked_words = Array<Type::Untracked>();
u64* const untracked_words = Array<Type::Untracked>();
u64* const state_words = Array<type>();
const u64 query_end = query_begin + std::min(static_cast<u64>(size), SizeBytes());
u64* const words_begin = state_words + query_begin / BYTES_PER_WORD;
@@ -483,7 +483,7 @@ private:
NotifyRasterizer<true>(word_index, current_bits, ~u64{0});
}
// Exclude CPU modified pages when visiting GPU pages
const u64 word = current_word;
const u64 word = current_word & ~(type == Type::GPU ? untracked_words[word_index] : 0);
u64 page = page_begin;
page_begin = 0;
@@ -531,7 +531,7 @@ private:
[[nodiscard]] bool IsRegionModified(u64 offset, u64 size) const noexcept {
static_assert(type != Type::Untracked);
[[maybe_unused]] const u64* const untracked_words = Array<Type::Untracked>();
const u64* const untracked_words = Array<Type::Untracked>();
const u64* const state_words = Array<type>();
const u64 num_query_words = size / BYTES_PER_WORD + 1;
const u64 word_begin = offset / BYTES_PER_WORD;
@@ -539,7 +539,8 @@ private:
const u64 page_limit = Common::DivCeil(offset + size, BYTES_PER_PAGE);
u64 page_index = (offset / BYTES_PER_PAGE) % PAGES_PER_WORD;
for (u64 word_index = word_begin; word_index < word_end; ++word_index, page_index = 0) {
const u64 word = state_words[word_index];
const u64 off_word = type == Type::GPU ? untracked_words[word_index] : 0;
const u64 word = state_words[word_index] & ~off_word;
if (word == 0) {
continue;
}
@@ -563,7 +564,7 @@ private:
[[nodiscard]] std::pair<u64, u64> ModifiedRegion(u64 offset, u64 size) const noexcept {
static_assert(type != Type::Untracked);
[[maybe_unused]] const u64* const untracked_words = Array<Type::Untracked>();
const u64* const untracked_words = Array<Type::Untracked>();
const u64* const state_words = Array<type>();
const u64 num_query_words = size / BYTES_PER_WORD + 1;
const u64 word_begin = offset / BYTES_PER_WORD;
@@ -573,7 +574,8 @@ private:
u64 begin = std::numeric_limits<u64>::max();
u64 end = 0;
for (u64 word_index = word_begin; word_index < word_end; ++word_index) {
const u64 word = state_words[word_index];
const u64 off_word = type == Type::GPU ? untracked_words[word_index] : 0;
const u64 word = state_words[word_index] & ~off_word;
if (word == 0) {
continue;
}

View File

@@ -99,7 +99,7 @@ struct GPU::Impl {
/// Signal the ending of command list.
void OnCommandListEnd() {
rasterizer->ReleaseFences();
gpu_thread.OnCommandListEnd();
}
/// Request a host GPU memory flush from the CPU.

View File

@@ -40,6 +40,8 @@ static void RunThread(std::stop_token stop_token, Core::System& system,
scheduler.Push(submit_list->channel, std::move(submit_list->entries));
} else if (const auto* data = std::get_if<SwapBuffersCommand>(&next.data)) {
renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr);
} else if (std::holds_alternative<OnCommandListEndCommand>(next.data)) {
rasterizer->ReleaseFences();
} else if (std::holds_alternative<GPUTickCommand>(next.data)) {
system.GPU().TickWork();
} else if (const auto* flush = std::get_if<FlushRegionCommand>(&next.data)) {
@@ -108,6 +110,10 @@ void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) {
rasterizer->OnCPUWrite(addr, size);
}
void ThreadManager::OnCommandListEnd() {
PushCommand(OnCommandListEndCommand());
}
u64 ThreadManager::PushCommand(CommandData&& command_data, bool block) {
if (!is_async) {
// In synchronous GPU mode, block the caller until the command has executed

View File

@@ -77,12 +77,16 @@ struct FlushAndInvalidateRegionCommand final {
u64 size;
};
/// Command called within the gpu, to schedule actions after a command list end
struct OnCommandListEndCommand final {};
/// Command to make the gpu look into pending requests
struct GPUTickCommand final {};
using CommandData =
std::variant<std::monostate, SubmitListCommand, SwapBuffersCommand, FlushRegionCommand,
InvalidateRegionCommand, FlushAndInvalidateRegionCommand, GPUTickCommand>;
InvalidateRegionCommand, FlushAndInvalidateRegionCommand, OnCommandListEndCommand,
GPUTickCommand>;
struct CommandDataContainer {
CommandDataContainer() = default;
@@ -130,6 +134,8 @@ public:
/// Notify rasterizer that any caches of the specified region should be flushed and invalidated
void FlushAndInvalidateRegion(VAddr addr, u64 size);
void OnCommandListEnd();
void TickGPU();
private:

View File

@@ -548,31 +548,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
static_vector<VkVertexInputBindingDescription, 32> vertex_bindings;
static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors;
static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes;
if (key.state.dynamic_vertex_input) {
const size_t num_vertex_arrays = std::min(
key.state.attributes.size(), static_cast<size_t>(device.GetMaxVertexInputBindings()));
for (size_t index = 0; index < num_vertex_arrays; ++index) {
const u32 type = key.state.DynamicAttributeType(index);
if (!stage_infos[0].loads.Generic(index) || type == 0) {
continue;
}
vertex_attributes.push_back({
.location = static_cast<u32>(index),
.binding = 0,
.format = type == 1 ? VK_FORMAT_R32_SFLOAT
: type == 2 ? VK_FORMAT_R32_SINT
: VK_FORMAT_R32_UINT,
.offset = 0,
});
}
if (!vertex_attributes.empty()) {
vertex_bindings.push_back({
.binding = 0,
.stride = 4,
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
});
}
} else {
if (!key.state.dynamic_vertex_input) {
const size_t num_vertex_arrays = std::min(
Maxwell::NumVertexArrays, static_cast<size_t>(device.GetMaxVertexInputBindings()));
for (size_t index = 0; index < num_vertex_arrays; ++index) {