Move puller members into the regs union
This commit is contained in:
@@ -34,7 +34,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
|
|||||||
maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
|
maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
|
||||||
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(rasterizer, *memory_manager);
|
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(rasterizer, *memory_manager);
|
||||||
kepler_memory = std::make_unique<Engines::KeplerMemory>(rasterizer, *memory_manager);
|
kepler_memory = std::make_unique<Engines::KeplerMemory>(rasterizer, *memory_manager);
|
||||||
pullerState.semaphore_off_val = true;
|
regs.semaphore_off_val = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU::~GPU() = default;
|
GPU::~GPU() = default;
|
||||||
@@ -285,25 +285,25 @@ void GPU::ProcessSemaphoreTriggerMethod() {
|
|||||||
// CoreTiming
|
// CoreTiming
|
||||||
const auto acquire_timestamp = CoreTiming::GetTicks();
|
const auto acquire_timestamp = CoreTiming::GetTicks();
|
||||||
if (op == GpuSemaphoreOperation::WriteLong) {
|
if (op == GpuSemaphoreOperation::WriteLong) {
|
||||||
Memory::Write32(pullerState.semaphore.SmaphoreAddress(), sequence);
|
Memory::Write32(regs.smaphore_address.SmaphoreAddress(), sequence);
|
||||||
Memory::Write32(pullerState.semaphore.SmaphoreAddress() + 0x4, 0);
|
Memory::Write32(regs.smaphore_address.SmaphoreAddress() + 0x4, 0);
|
||||||
Memory::Write64(pullerState.semaphore.SmaphoreAddress() + 0x8, acquire_timestamp);
|
Memory::Write64(regs.smaphore_address.SmaphoreAddress() + 0x8, acquire_timestamp);
|
||||||
} else {
|
} else {
|
||||||
const u32 word = Memory::Read32(pullerState.semaphore.SmaphoreAddress());
|
const u32 word = Memory::Read32(regs.smaphore_address.SmaphoreAddress());
|
||||||
if ((op == GpuSemaphoreOperation::AcquireEqual && word == pullerState.semaphore_sequence) ||
|
if ((op == GpuSemaphoreOperation::AcquireEqual && word == regs.semaphore_sequence) ||
|
||||||
(op == GpuSemaphoreOperation::AcquireGequal &&
|
(op == GpuSemaphoreOperation::AcquireGequal &&
|
||||||
static_cast<s32>(word - pullerState.semaphore_sequence) > 0) ||
|
static_cast<s32>(word - regs.semaphore_sequence) > 0) ||
|
||||||
(op == GpuSemaphoreOperation::AcquireMask && (word & pullerState.semaphore_sequence))) {
|
(op == GpuSemaphoreOperation::AcquireMask && (word & regs.semaphore_sequence))) {
|
||||||
// Nothing to do in this case
|
// Nothing to do in this case
|
||||||
} else {
|
} else {
|
||||||
pullerState.acquire_source = true;
|
regs.acquire_source = true;
|
||||||
pullerState.acquire_value = pullerState.semaphore_sequence;
|
regs.acquire_value = regs.semaphore_sequence;
|
||||||
if (op == GpuSemaphoreOperation::AcquireEqual) {
|
if (op == GpuSemaphoreOperation::AcquireEqual) {
|
||||||
pullerState.acquire_active = true;
|
regs.acquire_active = true;
|
||||||
pullerState.acquire_mode = false;
|
regs.acquire_mode = false;
|
||||||
} else if (op == GpuSemaphoreOperation::AcquireGequal) {
|
} else if (op == GpuSemaphoreOperation::AcquireGequal) {
|
||||||
pullerState.acquire_active = true;
|
regs.acquire_active = true;
|
||||||
pullerState.acquire_mode = true;
|
regs.acquire_mode = true;
|
||||||
} else if (op == GpuSemaphoreOperation::AcquireMask) {
|
} else if (op == GpuSemaphoreOperation::AcquireMask) {
|
||||||
// TODO(kemathe) The acquire mask operation waits for a value that, ANDed with
|
// TODO(kemathe) The acquire mask operation waits for a value that, ANDed with
|
||||||
// semaphore_sequence, gives a non-0 result
|
// semaphore_sequence, gives a non-0 result
|
||||||
@@ -316,27 +316,27 @@ void GPU::ProcessSemaphoreTriggerMethod() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GPU::ProcessSemaphoreRelease() {
|
void GPU::ProcessSemaphoreRelease() {
|
||||||
if (!pullerState.semaphore_off_val) {
|
if (!regs.semaphore_off_val) {
|
||||||
LOG_ERROR(HW_GPU, "Semaphore can't be released since it is not currently been acquired");
|
LOG_ERROR(HW_GPU, "Semaphore can't be released since it is not currently been acquired");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Memory::Write32(pullerState.semaphore.SmaphoreAddress(),
|
Memory::Write32(regs.smaphore_address.SmaphoreAddress(),
|
||||||
regs.reg_array[static_cast<u32>(BufferMethods::SemaphoreRelease)]);
|
regs.reg_array[static_cast<u32>(BufferMethods::SemaphoreRelease)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU::ProcessSemaphoreAcquire() {
|
void GPU::ProcessSemaphoreAcquire() {
|
||||||
if (!pullerState.semaphore_off_val) {
|
if (!regs.semaphore_off_val) {
|
||||||
LOG_ERROR(HW_GPU, "Semaphore has already be acquired");
|
LOG_ERROR(HW_GPU, "Semaphore has already be acquired");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const u32 word = Memory::Read32(pullerState.semaphore.SmaphoreAddress());
|
const u32 word = Memory::Read32(regs.smaphore_address.SmaphoreAddress());
|
||||||
const auto value = regs.reg_array[static_cast<u32>(BufferMethods::SemaphoreAcquire)];
|
const auto value = regs.reg_array[static_cast<u32>(BufferMethods::SemaphoreAcquire)];
|
||||||
if (word != value) {
|
if (word != value) {
|
||||||
pullerState.acquire_active = true;
|
regs.acquire_active = true;
|
||||||
pullerState.acquire_value = value;
|
regs.acquire_value = value;
|
||||||
// TODO(kemathe73) figure out how to do the acquire_timeout
|
// TODO(kemathe73) figure out how to do the acquire_timeout
|
||||||
pullerState.acquire_mode = false;
|
regs.acquire_mode = false;
|
||||||
pullerState.acquire_source = false;
|
regs.acquire_source = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void GPU::ProcessSetSemaphoreAddressHigh() {
|
void GPU::ProcessSetSemaphoreAddressHigh() {
|
||||||
@@ -346,7 +346,7 @@ void GPU::ProcessSetSemaphoreAddressHigh() {
|
|||||||
LOG_ERROR(HW_GPU, "SemaphoreAddressHigh too large");
|
LOG_ERROR(HW_GPU, "SemaphoreAddressHigh too large");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pullerState.semaphore.smaphore_address_high = addrHigh;
|
regs.smaphore_address.smaphore_address_high = addrHigh;
|
||||||
}
|
}
|
||||||
void GPU::ProcessSetSemaphoreAddressLow() {
|
void GPU::ProcessSetSemaphoreAddressLow() {
|
||||||
const auto addrLow = regs.reg_array[static_cast<u32>(BufferMethods::SemaphoreAddressLow)];
|
const auto addrLow = regs.reg_array[static_cast<u32>(BufferMethods::SemaphoreAddressLow)];
|
||||||
@@ -355,21 +355,17 @@ void GPU::ProcessSetSemaphoreAddressLow() {
|
|||||||
LOG_ERROR(HW_GPU, "SemaphoreAddressLow unaligned");
|
LOG_ERROR(HW_GPU, "SemaphoreAddressLow unaligned");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pullerState.semaphore.smaphore_address_low = addrLow;
|
regs.smaphore_address.smaphore_address_low = addrLow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU::SetReferenceCount() {
|
void GPU::SetReferenceCount() {
|
||||||
// TODO(kmather73) Wait for all previously submitted commands complete before setting.
|
// TODO(kmather73) Wait for all previously submitted commands complete before setting.
|
||||||
pullerState.reference_count = regs.reg_array[static_cast<u32>(BufferMethods::RefCnt)];
|
regs.reference_count = regs.reg_array[static_cast<u32>(BufferMethods::RefCnt)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU::ProcessSetSemaphoreSequence() {
|
void GPU::ProcessSetSemaphoreSequence() {
|
||||||
pullerState.semaphore_sequence =
|
regs.semaphore_sequence =
|
||||||
regs.reg_array[static_cast<u32>(BufferMethods::SemaphoreSequence)];
|
regs.reg_array[static_cast<u32>(BufferMethods::SemaphoreSequence)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 GPU::ReferenceCount() const {
|
|
||||||
return pullerState.reference_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Tegra
|
} // namespace Tegra
|
||||||
|
|||||||
@@ -156,8 +156,36 @@ public:
|
|||||||
/// Returns a const reference to the GPU DMA pusher.
|
/// Returns a const reference to the GPU DMA pusher.
|
||||||
const Tegra::DmaPusher& DmaPusher() const;
|
const Tegra::DmaPusher& DmaPusher() const;
|
||||||
|
|
||||||
// The puser and the puller share the reference counter, the pusher only had read access
|
struct Regs {
|
||||||
const u32 ReferenceCount() const;
|
static constexpr size_t NUM_REGS = 0x140;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
u32 acquire_mode;
|
||||||
|
u32 acquire_source;
|
||||||
|
// The puser and the puller share the reference counter, the pusher only has read
|
||||||
|
// access
|
||||||
|
u32 reference_count;
|
||||||
|
u32 acquire_active;
|
||||||
|
u32 acquire_timeout;
|
||||||
|
u32 acquire_value;
|
||||||
|
u32 semaphore_off_val;
|
||||||
|
u32 semaphore_sequence;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u32 smaphore_address_high;
|
||||||
|
u32 smaphore_address_low;
|
||||||
|
|
||||||
|
GPUVAddr SmaphoreAddress() const {
|
||||||
|
return static_cast<GPUVAddr>(
|
||||||
|
(static_cast<GPUVAddr>(smaphore_address_high) << 32) |
|
||||||
|
smaphore_address_low);
|
||||||
|
}
|
||||||
|
} smaphore_address;
|
||||||
|
};
|
||||||
|
std::array<u32, NUM_REGS> reg_array;
|
||||||
|
};
|
||||||
|
} regs{};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Tegra::DmaPusher> dma_pusher;
|
std::unique_ptr<Tegra::DmaPusher> dma_pusher;
|
||||||
@@ -177,34 +205,6 @@ private:
|
|||||||
/// Inline memory engine
|
/// Inline memory engine
|
||||||
std::unique_ptr<Engines::KeplerMemory> kepler_memory;
|
std::unique_ptr<Engines::KeplerMemory> kepler_memory;
|
||||||
|
|
||||||
struct Regs {
|
|
||||||
static constexpr size_t NUM_REGS = 0x40;
|
|
||||||
|
|
||||||
union {
|
|
||||||
std::array<u32, NUM_REGS> reg_array;
|
|
||||||
};
|
|
||||||
} regs{};
|
|
||||||
|
|
||||||
struct {
|
|
||||||
u32 reference_count;
|
|
||||||
bool acquire_active;
|
|
||||||
u32 acquire_timeout;
|
|
||||||
u32 acquire_value;
|
|
||||||
bool semaphore_off_val;
|
|
||||||
struct {
|
|
||||||
u8 smaphore_address_high;
|
|
||||||
u32 smaphore_address_low;
|
|
||||||
|
|
||||||
GPUVAddr SmaphoreAddress() const {
|
|
||||||
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(smaphore_address_high) << 32) |
|
|
||||||
smaphore_address_low);
|
|
||||||
}
|
|
||||||
} semaphore;
|
|
||||||
u32 semaphore_sequence;
|
|
||||||
bool acquire_mode;
|
|
||||||
bool acquire_source;
|
|
||||||
} pullerState{};
|
|
||||||
|
|
||||||
void ProcessBindMethod(const MethodCall& method_call);
|
void ProcessBindMethod(const MethodCall& method_call);
|
||||||
void ProcessSemaphoreTriggerMethod();
|
void ProcessSemaphoreTriggerMethod();
|
||||||
void ProcessSemaphoreRelease();
|
void ProcessSemaphoreRelease();
|
||||||
@@ -222,4 +222,19 @@ private:
|
|||||||
bool ExecuteMethodOnEngine(const MethodCall& method_call);
|
bool ExecuteMethodOnEngine(const MethodCall& method_call);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ASSERT_REG_POSITION(field_name, position) \
|
||||||
|
static_assert(offsetof(GPU::Regs, field_name) == position * 4, \
|
||||||
|
"Field " #field_name " has invalid position")
|
||||||
|
|
||||||
|
ASSERT_REG_POSITION(acquire_mode, 0x0);
|
||||||
|
ASSERT_REG_POSITION(acquire_source, 0x1);
|
||||||
|
ASSERT_REG_POSITION(reference_count, 0x2);
|
||||||
|
ASSERT_REG_POSITION(acquire_active, 0x3);
|
||||||
|
ASSERT_REG_POSITION(acquire_timeout, 0x4);
|
||||||
|
ASSERT_REG_POSITION(acquire_value, 0x5);
|
||||||
|
ASSERT_REG_POSITION(semaphore_off_val, 0x6);
|
||||||
|
ASSERT_REG_POSITION(semaphore_sequence, 0x7);
|
||||||
|
ASSERT_REG_POSITION(smaphore_address, 0x8);
|
||||||
|
#undef ASSERT_REG_POSITION
|
||||||
|
|
||||||
} // namespace Tegra
|
} // namespace Tegra
|
||||||
|
|||||||
Reference in New Issue
Block a user