summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-06-07 17:34:55 +0200
committerFernandoS27 <fsahmkow27@gmail.com>2019-07-05 21:49:10 +0200
commit737e978f5b1440a044ef90f346c8616c2de49a81 (patch)
tree42b3c99171a3929f64db141db81193a0067b3523 /src/core/hle
parentnvflinger: Implement swap intervals (diff)
downloadyuzu-737e978f5b1440a044ef90f346c8616c2de49a81.tar
yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.tar.gz
yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.tar.bz2
yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.tar.lz
yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.tar.xz
yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.tar.zst
yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.zip
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h22
-rw-r--r--src/core/hle/service/nvdrv/nvdata.h25
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h8
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp9
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h8
-rw-r--r--src/core/hle/service/vi/vi.cpp46
7 files changed, 69 insertions, 57 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 8ce7bc7a5..8a53eddb1 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -155,8 +155,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries));
- params.fence_out.id = 0;
- params.fence_out.value = 0;
+ // TODO(Blinkhawk): Figure how thoios fence is set
+ // params.fence_out.value = 0;
std::memcpy(output.data(), &params, sizeof(IoctlSubmitGpfifo));
return 0;
}
@@ -176,8 +176,8 @@ u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output)
Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries));
- params.fence_out.id = 0;
- params.fence_out.value = 0;
+ // TODO(Blinkhawk): Figure how thoios fence is set
+ // params.fence_out.value = 0;
std::memcpy(output.data(), &params, output.size());
return 0;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index 62beb5c0c..d95cedb09 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -113,11 +113,11 @@ private:
static_assert(sizeof(IoctlGetErrorNotification) == 16,
"IoctlGetErrorNotification is incorrect size");
- struct IoctlFence {
+ struct Fence {
u32_le id;
u32_le value;
};
- static_assert(sizeof(IoctlFence) == 8, "IoctlFence is incorrect size");
+ static_assert(sizeof(Fence) == 8, "Fence is incorrect size");
struct IoctlAllocGpfifoEx {
u32_le num_entries;
@@ -132,13 +132,13 @@ private:
static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx is incorrect size");
struct IoctlAllocGpfifoEx2 {
- u32_le num_entries; // in
- u32_le flags; // in
- u32_le unk0; // in (1 works)
- IoctlFence fence_out; // out
- u32_le unk1; // in
- u32_le unk2; // in
- u32_le unk3; // in
+ u32_le num_entries; // in
+ u32_le flags; // in
+ u32_le unk0; // in (1 works)
+ Fence fence_out; // out
+ u32_le unk1; // in
+ u32_le unk2; // in
+ u32_le unk3; // in
};
static_assert(sizeof(IoctlAllocGpfifoEx2) == 32, "IoctlAllocGpfifoEx2 is incorrect size");
@@ -154,9 +154,9 @@ private:
u64_le address; // pointer to gpfifo entry structs
u32_le num_entries; // number of fence objects being submitted
u32_le flags;
- IoctlFence fence_out; // returned new fence object for others to wait on
+ Fence fence_out; // returned new fence object for others to wait on
};
- static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(IoctlFence),
+ static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(Fence),
"IoctlSubmitGpfifo is incorrect size");
struct IoctlGetWaitbase {
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h
new file mode 100644
index 000000000..7e1dce232
--- /dev/null
+++ b/src/core/hle/service/nvdrv/nvdata.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <array>
+#include "common/common_types.h"
+
+namespace Service::Nvidia {
+
+struct Fence {
+ s32 id;
+ u32 value;
+};
+
+static_assert(sizeof(Fence) == 8, "Fence has wrong size");
+
+struct MultiFence {
+ u32 num_fences;
+ std::array<Fence, 4> fences;
+};
+
+enum class NvResult : u32 {
+ Success = 0,
+ TryAgain = 11,
+};
+
+} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index 53564f696..bacd7cdb7 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -8,6 +8,7 @@
#include <unordered_map>
#include <vector>
#include "common/common_types.h"
+#include "core/hle/service/nvdrv/nvdata.h"
#include "core/hle/service/service.h"
namespace Service::NVFlinger {
@@ -20,13 +21,6 @@ namespace Devices {
class nvdevice;
}
-struct IoctlFence {
- u32 id;
- u32 value;
-};
-
-static_assert(sizeof(IoctlFence) == 8, "IoctlFence has wrong size");
-
class Module final {
public:
Module();
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index dca75c35e..75e47b8c7 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -34,7 +34,8 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
buffer_wait_event.writable->Signal();
}
-std::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
+std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width,
+ u32 height) {
auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
// Only consider free buffers. Buffers become free once again after they've been Acquired
// and Released by the compositor, see the NVFlinger::Compose method.
@@ -51,7 +52,7 @@ std::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
}
itr->status = Buffer::Status::Dequeued;
- return itr->slot;
+ return {{itr->slot, &itr->multi_fence}};
}
const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const {
@@ -63,7 +64,8 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const {
}
void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
- const Common::Rectangle<int>& crop_rect, u32 swap_interval) {
+ const Common::Rectangle<int>& crop_rect, u32 swap_interval,
+ Service::Nvidia::MultiFence& multi_fence) {
auto itr = std::find_if(queue.begin(), queue.end(),
[&](const Buffer& buffer) { return buffer.slot == slot; });
ASSERT(itr != queue.end());
@@ -72,6 +74,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
itr->transform = transform;
itr->crop_rect = crop_rect;
itr->swap_interval = swap_interval;
+ itr->multi_fence = multi_fence;
}
std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index 139b98b9f..c163e565c 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -12,6 +12,7 @@
#include "common/swap.h"
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/writable_event.h"
+#include "core/hle/service/nvdrv/nvdata.h"
namespace Service::NVFlinger {
@@ -69,13 +70,16 @@ public:
BufferTransformFlags transform;
Common::Rectangle<int> crop_rect;
u32 swap_interval;
+ Service::Nvidia::MultiFence multi_fence;
};
void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer);
- std::optional<u32> DequeueBuffer(u32 width, u32 height);
+ std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> DequeueBuffer(u32 width,
+ u32 height);
const IGBPBuffer& RequestBuffer(u32 slot) const;
void QueueBuffer(u32 slot, BufferTransformFlags transform,
- const Common::Rectangle<int>& crop_rect, u32 swap_interval);
+ const Common::Rectangle<int>& crop_rect, u32 swap_interval,
+ Service::Nvidia::MultiFence& multi_fence);
std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer();
void ReleaseBuffer(u32 slot);
u32 Query(QueryType type);
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 55bd252c2..894bcdc04 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -21,6 +21,7 @@
#include "core/hle/kernel/readable_event.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/writable_event.h"
+#include "core/hle/service/nvdrv/nvdata.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/nvflinger/buffer_queue.h"
#include "core/hle/service/nvflinger/nvflinger.h"
@@ -328,32 +329,22 @@ public:
Data data;
};
-struct BufferProducerFence {
- u32 is_valid;
- std::array<Nvidia::IoctlFence, 4> fences;
-};
-static_assert(sizeof(BufferProducerFence) == 36, "BufferProducerFence has wrong size");
-
class IGBPDequeueBufferResponseParcel : public Parcel {
public:
- explicit IGBPDequeueBufferResponseParcel(u32 slot) : slot(slot) {}
+ explicit IGBPDequeueBufferResponseParcel(u32 slot, Service::Nvidia::MultiFence& multi_fence)
+ : slot(slot), multi_fence(multi_fence) {}
~IGBPDequeueBufferResponseParcel() override = default;
protected:
void SerializeData() override {
- // TODO(Subv): Find out how this Fence is used.
- BufferProducerFence fence = {};
- fence.is_valid = 1;
- for (auto& fence_ : fence.fences)
- fence_.id = -1;
-
Write(slot);
Write<u32_le>(1);
- WriteObject(fence);
+ WriteObject(multi_fence);
Write<u32_le>(0);
}
u32_le slot;
+ Service::Nvidia::MultiFence multi_fence;
};
class IGBPRequestBufferRequestParcel : public Parcel {
@@ -400,12 +391,6 @@ public:
data = Read<Data>();
}
- struct Fence {
- u32_le id;
- u32_le value;
- };
- static_assert(sizeof(Fence) == 8, "Fence has wrong size");
-
struct Data {
u32_le slot;
INSERT_PADDING_WORDS(3);
@@ -420,14 +405,13 @@ public:
u32_le sticky_transform;
INSERT_PADDING_WORDS(1);
u32_le swap_interval;
- u32_le fence_is_valid;
- std::array<Fence, 2> fences;
+ Service::Nvidia::MultiFence multi_fence;
Common::Rectangle<int> GetCropRect() const {
return {crop_left, crop_top, crop_right, crop_bottom};
}
};
- static_assert(sizeof(Data) == 80, "ParcelData has wrong size");
+ static_assert(sizeof(Data) == 96, "ParcelData has wrong size");
Data data;
};
@@ -548,11 +532,11 @@ private:
IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()};
const u32 width{request.data.width};
const u32 height{request.data.height};
- std::optional<u32> slot = buffer_queue.DequeueBuffer(width, height);
+ auto result = buffer_queue.DequeueBuffer(width, height);
- if (slot) {
+ if (result) {
// Buffer is available
- IGBPDequeueBufferResponseParcel response{*slot};
+ IGBPDequeueBufferResponseParcel response{(*result).first, *(*result).second};
ctx.WriteBuffer(response.Serialize());
} else {
// Wait the current thread until a buffer becomes available
@@ -562,10 +546,11 @@ private:
Kernel::ThreadWakeupReason reason) {
// Repeat TransactParcel DequeueBuffer when a buffer is available
auto& buffer_queue = nv_flinger->FindBufferQueue(id);
- std::optional<u32> slot = buffer_queue.DequeueBuffer(width, height);
- ASSERT_MSG(slot != std::nullopt, "Could not dequeue buffer.");
+ auto result = buffer_queue.DequeueBuffer(width, height);
+ ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer.");
- IGBPDequeueBufferResponseParcel response{*slot};
+ IGBPDequeueBufferResponseParcel response{(*result).first,
+ *(*result).second};
ctx.WriteBuffer(response.Serialize());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -583,7 +568,8 @@ private:
IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()};
buffer_queue.QueueBuffer(request.data.slot, request.data.transform,
- request.data.GetCropRect(), request.data.swap_interval);
+ request.data.GetCropRect(), request.data.swap_interval,
+ request.data.multi_fence);
IGBPQueueBufferResponseParcel response{1280, 720};
ctx.WriteBuffer(response.Serialize());