mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-27 16:55:29 +03:00
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:
parent
dbb684835f
commit
f52ea7bddb
@ -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) {
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user