Force a submit before any i2m engine writes

We need traps to be inplace so we dont end up overwriting a resource that's being actively used by the current context without setting it to dirty
This commit is contained in:
Billy Laws 2022-07-31 13:21:26 +01:00
parent cb0b132486
commit 0268e1d5a0
5 changed files with 13 additions and 11 deletions

View File

@ -13,6 +13,6 @@ namespace skyline::soc::gm20b {
fermi2D(std::make_unique<engine::fermi2d::Fermi2D>(state, *this, macroState, executor)),
maxwellDma(state, *this, executor),
keplerCompute(state, *this),
inline2Memory(asCtx),
inline2Memory(*this),
gpfifo(state, *this, numEntries) {}
}

View File

@ -1,11 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <soc/gm20b/gmmu.h>
#include <soc/gm20b/channel.h>
#include "inline2memory.h"
namespace skyline::soc::gm20b::engine {
Inline2MemoryBackend::Inline2MemoryBackend(std::shared_ptr<AddressSpaceContext> addressSpaceContext) : addressSpaceContext(std::move(addressSpaceContext)) {}
Inline2MemoryBackend::Inline2MemoryBackend(ChannelContext &channelCtx) : channelCtx(channelCtx) {}
void Inline2MemoryBackend::LaunchDma(Inline2MemoryBackend::RegisterState &state) {
writeOffset = 0;
@ -17,10 +17,12 @@ namespace skyline::soc::gm20b::engine {
if (state.launchDma.completion == RegisterState::DmaCompletionType::ReleaseSemaphore)
throw exception("Semaphore release on I2M completion is not supported!");
channelCtx.executor.Submit();
if (state.launchDma.layout == RegisterState::DmaDstMemoryLayout::Pitch && state.lineCount == 1) {
// TODO: we can do this with the buffer manager to avoid some overhead in the future
Logger::Debug("range: 0x{:X} -> 0x{:X}", u64{state.offsetOut}, u64{state.offsetOut} + buffer.size() * 0x4);
addressSpaceContext->gmmu.Write(state.offsetOut, span(buffer));
channelCtx.asCtx->gmmu.Write(state.offsetOut, span(buffer));
} else {
Logger::Warn("Non-linear I2M uploads are not supported!");
}
@ -47,7 +49,7 @@ namespace skyline::soc::gm20b::engine {
CompleteDma(state);
}
Inline2Memory::Inline2Memory(std::shared_ptr<AddressSpaceContext> addressSpaceContext) : backend(std::move(addressSpaceContext)) {}
Inline2Memory::Inline2Memory(ChannelContext &channelCtx) : backend(channelCtx) {}
__attribute__((always_inline)) void Inline2Memory::CallMethod(u32 method, u32 argument) {
Logger::Verbose("Called method in I2M: 0x{:X} args: 0x{:X}", method, argument);

View File

@ -7,7 +7,7 @@
#include "engine.h"
namespace skyline::soc::gm20b {
struct AddressSpaceContext;
struct ChannelContext;
}
namespace skyline::soc::gm20b::engine {
@ -18,7 +18,7 @@ namespace skyline::soc::gm20b::engine {
private:
std::vector<u32> buffer; //!< Temporary buffer to hold data being currently uploaded
u32 writeOffset{}; //!< Current write offset in words into `buffer`
std::shared_ptr<AddressSpaceContext> addressSpaceContext;
ChannelContext &channelCtx;
public:
/**
@ -124,7 +124,7 @@ namespace skyline::soc::gm20b::engine {
void CompleteDma(RegisterState &state);
public:
Inline2MemoryBackend(std::shared_ptr<AddressSpaceContext> addressSpaceContext);
Inline2MemoryBackend(ChannelContext &channelCtx);
/**
* @brief Should be called when launchDma in `state` is written to
@ -164,7 +164,7 @@ namespace skyline::soc::gm20b::engine {
} registers{};
public:
Inline2Memory(std::shared_ptr<AddressSpaceContext> addressSpaceContext);
Inline2Memory(ChannelContext &channelCtx);
void CallMethod(u32 method, u32 argument);

View File

@ -8,7 +8,7 @@
namespace skyline::soc::gm20b::engine {
KeplerCompute::KeplerCompute(const DeviceState &state, ChannelContext &channelCtx)
: syncpoints(state.soc->host1x.syncpoints), i2m(channelCtx.asCtx) {}
: syncpoints(state.soc->host1x.syncpoints), i2m(channelCtx) {}
__attribute__((always_inline)) void KeplerCompute::CallMethod(u32 method, u32 argument) {
Logger::Verbose("Called method in Kepler compute: 0x{:X} args: 0x{:X}", method, argument);

View File

@ -11,7 +11,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
: MacroEngineBase(macroState),
syncpoints(state.soc->host1x.syncpoints),
context(*state.gpu, channelCtx, executor),
i2m(channelCtx.asCtx),
i2m(channelCtx),
channelCtx(channelCtx) {
executor.AddFlushCallback([this]() { FlushEngineState(); });
InitializeRegisters();