mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-11-24 08:32:57 +00:00
video_core: gpu: Implement WaitFence and IncrementSyncPoint.
This commit is contained in:
parent
66edfd61c6
commit
6053b95552
|
@ -27,6 +27,31 @@ enum class SubmissionMode : u32 {
|
||||||
IncreaseOnce = 5
|
IncreaseOnce = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Note that, traditionally, methods are treated as 4-byte addressable locations, and hence
|
||||||
|
// their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4.
|
||||||
|
// So the values you see in docs might be multiplied by 4.
|
||||||
|
enum class BufferMethods : u32 {
|
||||||
|
BindObject = 0x0,
|
||||||
|
Nop = 0x2,
|
||||||
|
SemaphoreAddressHigh = 0x4,
|
||||||
|
SemaphoreAddressLow = 0x5,
|
||||||
|
SemaphoreSequence = 0x6,
|
||||||
|
SemaphoreTrigger = 0x7,
|
||||||
|
NotifyIntr = 0x8,
|
||||||
|
WrcacheFlush = 0x9,
|
||||||
|
Unk28 = 0xA,
|
||||||
|
UnkCacheFlush = 0xB,
|
||||||
|
RefCnt = 0x14,
|
||||||
|
SemaphoreAcquire = 0x1A,
|
||||||
|
SemaphoreRelease = 0x1B,
|
||||||
|
FenceValue = 0x1C,
|
||||||
|
FenceAction = 0x1D,
|
||||||
|
WaitForInterrupt = 0x1E,
|
||||||
|
Unk7c = 0x1F,
|
||||||
|
Yield = 0x20,
|
||||||
|
NonPullerMethods = 0x40,
|
||||||
|
};
|
||||||
|
|
||||||
struct CommandListHeader {
|
struct CommandListHeader {
|
||||||
union {
|
union {
|
||||||
u64 raw;
|
u64 raw;
|
||||||
|
|
|
@ -194,30 +194,6 @@ void GPU::SyncGuestHost() {
|
||||||
void GPU::OnCommandListEnd() {
|
void GPU::OnCommandListEnd() {
|
||||||
renderer->Rasterizer().ReleaseFences();
|
renderer->Rasterizer().ReleaseFences();
|
||||||
}
|
}
|
||||||
// Note that, traditionally, methods are treated as 4-byte addressable locations, and hence
|
|
||||||
// their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4.
|
|
||||||
// So the values you see in docs might be multiplied by 4.
|
|
||||||
enum class BufferMethods {
|
|
||||||
BindObject = 0x0,
|
|
||||||
Nop = 0x2,
|
|
||||||
SemaphoreAddressHigh = 0x4,
|
|
||||||
SemaphoreAddressLow = 0x5,
|
|
||||||
SemaphoreSequence = 0x6,
|
|
||||||
SemaphoreTrigger = 0x7,
|
|
||||||
NotifyIntr = 0x8,
|
|
||||||
WrcacheFlush = 0x9,
|
|
||||||
Unk28 = 0xA,
|
|
||||||
UnkCacheFlush = 0xB,
|
|
||||||
RefCnt = 0x14,
|
|
||||||
SemaphoreAcquire = 0x1A,
|
|
||||||
SemaphoreRelease = 0x1B,
|
|
||||||
FenceValue = 0x1C,
|
|
||||||
FenceAction = 0x1D,
|
|
||||||
Unk78 = 0x1E,
|
|
||||||
Unk7c = 0x1F,
|
|
||||||
Yield = 0x20,
|
|
||||||
NonPullerMethods = 0x40,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class GpuSemaphoreOperation {
|
enum class GpuSemaphoreOperation {
|
||||||
AcquireEqual = 0x1,
|
AcquireEqual = 0x1,
|
||||||
|
@ -277,7 +253,12 @@ void GPU::CallPullerMethod(const MethodCall& method_call) {
|
||||||
case BufferMethods::UnkCacheFlush:
|
case BufferMethods::UnkCacheFlush:
|
||||||
case BufferMethods::WrcacheFlush:
|
case BufferMethods::WrcacheFlush:
|
||||||
case BufferMethods::FenceValue:
|
case BufferMethods::FenceValue:
|
||||||
|
break;
|
||||||
case BufferMethods::FenceAction:
|
case BufferMethods::FenceAction:
|
||||||
|
ProcessFenceActionMethod();
|
||||||
|
break;
|
||||||
|
case BufferMethods::WaitForInterrupt:
|
||||||
|
ProcessWaitForInterruptMethod();
|
||||||
break;
|
break;
|
||||||
case BufferMethods::SemaphoreTrigger: {
|
case BufferMethods::SemaphoreTrigger: {
|
||||||
ProcessSemaphoreTriggerMethod();
|
ProcessSemaphoreTriggerMethod();
|
||||||
|
@ -391,6 +372,25 @@ void GPU::ProcessBindMethod(const MethodCall& method_call) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GPU::ProcessFenceActionMethod() {
|
||||||
|
switch (regs.fence_action.op) {
|
||||||
|
case FenceOperation::Acquire:
|
||||||
|
WaitFence(regs.fence_action.syncpoint_id, regs.fence_value);
|
||||||
|
break;
|
||||||
|
case FenceOperation::Increment:
|
||||||
|
IncrementSyncPoint(regs.fence_action.syncpoint_id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNIMPLEMENTED_MSG("Unimplemented operation {}",
|
||||||
|
static_cast<u32>(regs.fence_action.op.Value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GPU::ProcessWaitForInterruptMethod() {
|
||||||
|
// TODO(bunnei) ImplementMe
|
||||||
|
LOG_WARNING(HW_GPU, "(STUBBED) called");
|
||||||
|
}
|
||||||
|
|
||||||
void GPU::ProcessSemaphoreTriggerMethod() {
|
void GPU::ProcessSemaphoreTriggerMethod() {
|
||||||
const auto semaphoreOperationMask = 0xF;
|
const auto semaphoreOperationMask = 0xF;
|
||||||
const auto op =
|
const auto op =
|
||||||
|
|
|
@ -263,6 +263,24 @@ public:
|
||||||
return use_nvdec;
|
return use_nvdec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class FenceOperation : u32 {
|
||||||
|
Acquire = 0,
|
||||||
|
Increment = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
union FenceAction {
|
||||||
|
u32 raw;
|
||||||
|
BitField<0, 1, FenceOperation> op;
|
||||||
|
BitField<8, 24, u32> syncpoint_id;
|
||||||
|
|
||||||
|
static constexpr CommandHeader Build(FenceOperation op, u32 syncpoint_id) {
|
||||||
|
FenceAction result{};
|
||||||
|
result.op.Assign(op);
|
||||||
|
result.syncpoint_id.Assign(syncpoint_id);
|
||||||
|
return {result.raw};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct Regs {
|
struct Regs {
|
||||||
static constexpr size_t NUM_REGS = 0x40;
|
static constexpr size_t NUM_REGS = 0x40;
|
||||||
|
|
||||||
|
@ -291,10 +309,7 @@ public:
|
||||||
u32 semaphore_acquire;
|
u32 semaphore_acquire;
|
||||||
u32 semaphore_release;
|
u32 semaphore_release;
|
||||||
u32 fence_value;
|
u32 fence_value;
|
||||||
union {
|
FenceAction fence_action;
|
||||||
BitField<4, 4, u32> operation;
|
|
||||||
BitField<8, 8, u32> id;
|
|
||||||
} fence_action;
|
|
||||||
INSERT_UNION_PADDING_WORDS(0xE2);
|
INSERT_UNION_PADDING_WORDS(0xE2);
|
||||||
|
|
||||||
// Puller state
|
// Puller state
|
||||||
|
@ -342,6 +357,8 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ProcessBindMethod(const MethodCall& method_call);
|
void ProcessBindMethod(const MethodCall& method_call);
|
||||||
|
void ProcessFenceActionMethod();
|
||||||
|
void ProcessWaitForInterruptMethod();
|
||||||
void ProcessSemaphoreTriggerMethod();
|
void ProcessSemaphoreTriggerMethod();
|
||||||
void ProcessSemaphoreRelease();
|
void ProcessSemaphoreRelease();
|
||||||
void ProcessSemaphoreAcquire();
|
void ProcessSemaphoreAcquire();
|
||||||
|
|
Loading…
Reference in a new issue