diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.cpp b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.cpp index f01fbdbb..bd5aa04a 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.cpp @@ -14,10 +14,19 @@ namespace skyline::gpu::interconnect::maxwell3d { ConstantBufferSelectorState::ConstantBufferSelectorState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) : engine{manager, dirtyHandle, engine} {} - void ConstantBufferSelectorState::Flush(InterconnectContext &ctx) { + void ConstantBufferSelectorState::Flush(InterconnectContext &ctx, size_t minSize) { const auto &selector{engine->constantBufferSelector}; // Constant buffer selector size is often left at the default value of 0x10000 which can end up being larger than the underlying mapping so avoid warning for split mappings here - view.Update(ctx, selector.address, selector.size, false); + view.Update(ctx, selector.address, std::max(minSize, selector.size), false); + } + + bool ConstantBufferSelectorState::Refresh(InterconnectContext &ctx, size_t minSize) { + const auto &selector{engine->constantBufferSelector}; + size_t selectorMinSize{std::max(minSize, selector.size)}; + if (view->size != selectorMinSize) + view.Update(ctx, selector.address, selectorMinSize, false); + + return false; } void ConstantBufferSelectorState::PurgeCaches() { @@ -42,7 +51,7 @@ namespace skyline::gpu::interconnect::maxwell3d { } void ConstantBuffers::Load(InterconnectContext &ctx, span data, u32 offset) { - auto &view{*selectorState.UpdateGet(ctx).view}; + auto &view{*selectorState.UpdateGet(ctx, data.size_bytes()).view}; auto srcCpuBuf{data.cast()}; ctx.executor.AcquireBufferManager(); @@ -79,6 +88,9 @@ namespace skyline::gpu::interconnect::maxwell3d { void ConstantBuffers::Bind(InterconnectContext &ctx, engine::ShaderStage stage, size_t index) { auto &view{*selectorState.UpdateGet(ctx).view}; + if (!view) + throw exception("Constant buffer selector is not mapped"); + boundConstantBuffers[static_cast(stage)][index] = {view}; if (quickBindEnabled && quickBind) diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.h index 3569f7e7..e0815759 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.h @@ -6,7 +6,7 @@ #include "common.h" namespace skyline::gpu::interconnect::maxwell3d { - class ConstantBufferSelectorState : dirty::CachedManualDirty { + class ConstantBufferSelectorState : dirty::CachedManualDirty, dirty::RefreshableManualDirty { public: struct EngineRegisters { const engine::ConstantBufferSelector &constantBufferSelector; @@ -22,7 +22,9 @@ namespace skyline::gpu::interconnect::maxwell3d { CachedMappedBufferView view; - void Flush(InterconnectContext &ctx); + void Flush(InterconnectContext &ctx, size_t minSize = 0); + + bool Refresh(InterconnectContext &ctx, size_t minSize = 0); void PurgeCaches(); };