Make deferred draw and constant buffer updates reentrant-safe

At some point we will call Submit within draws or constant buffer updates, to avoid any infinite recursion mark draw/cbuf pending as false before performing any operation
This commit is contained in:
Billy Laws 2022-07-29 20:02:47 +01:00
parent dbb684835f
commit f52ea7bddb
2 changed files with 10 additions and 6 deletions

View File

@ -19,12 +19,13 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
void Maxwell3D::FlushDeferredDraw() { void Maxwell3D::FlushDeferredDraw() {
if (deferredDraw.pending) { if (deferredDraw.pending) {
deferredDraw.pending = false;
if (deferredDraw.indexed) if (deferredDraw.indexed)
context.DrawIndexed(deferredDraw.drawCount, deferredDraw.drawFirst, deferredDraw.instanceCount, deferredDraw.drawBaseVertex); context.DrawIndexed(deferredDraw.drawCount, deferredDraw.drawFirst, deferredDraw.instanceCount, deferredDraw.drawBaseVertex);
else else
context.Draw(deferredDraw.drawCount, deferredDraw.drawFirst, deferredDraw.instanceCount); context.Draw(deferredDraw.drawCount, deferredDraw.drawFirst, deferredDraw.instanceCount);
deferredDraw.pending = false;
deferredDraw.instanceCount = 1; deferredDraw.instanceCount = 1;
} }
} }
@ -55,7 +56,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
#undef CBUF_UPDATE_CALLBACKS #undef CBUF_UPDATE_CALLBACKS
default: default:
// When a method other than constant buffer update is called submit our submit the previously built-up update as a batch // When a method other than constant buffer update is called submit our submit the previously built-up update as a batch
context.ConstantBufferUpdate(std::move(batchConstantBufferUpdate.buffer), batchConstantBufferUpdate.startOffset); context.ConstantBufferUpdate(batchConstantBufferUpdate.buffer, batchConstantBufferUpdate.Invalidate());
batchConstantBufferUpdate.Reset(); batchConstantBufferUpdate.Reset();
break; // Continue on here to handle the actual method break; // Continue on here to handle the actual method
} }
@ -771,12 +772,12 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
} }
void Maxwell3D::FlushEngineState() { void Maxwell3D::FlushEngineState() {
FlushDeferredDraw();
if (batchConstantBufferUpdate.Active()) { if (batchConstantBufferUpdate.Active()) {
context.ConstantBufferUpdate(std::move(batchConstantBufferUpdate.buffer), batchConstantBufferUpdate.startOffset); context.ConstantBufferUpdate(batchConstantBufferUpdate.buffer, batchConstantBufferUpdate.Invalidate());
batchConstantBufferUpdate.Reset(); batchConstantBufferUpdate.Reset();
} }
FlushDeferredDraw();
} }
__attribute__((always_inline)) void Maxwell3D::CallMethod(u32 method, u32 argument) { __attribute__((always_inline)) void Maxwell3D::CallMethod(u32 method, u32 argument) {

View File

@ -31,9 +31,12 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
return startOffset != std::numeric_limits<u32>::max(); return startOffset != std::numeric_limits<u32>::max();
} }
u32 Invalidate() {
return std::exchange(startOffset, std::numeric_limits<u32>::max());
}
void Reset() { void Reset() {
buffer.clear(); buffer.clear();
startOffset = std::numeric_limits<u32>::max();
} }
} batchConstantBufferUpdate; //!< Holds state for updating constant buffer data in a batch rather than word by word } batchConstantBufferUpdate; //!< Holds state for updating constant buffer data in a batch rather than word by word