Ignore constant buffer selector size for updates

Clustertruck performs a giant (0x3000 byte) update with a selector size of only 0x500, without this the update would only partially go through
This commit is contained in:
Billy Laws 2022-09-29 21:05:04 +01:00
parent 33f16ca26e
commit 92ce220d3a
2 changed files with 19 additions and 5 deletions

View File

@ -14,10 +14,19 @@ namespace skyline::gpu::interconnect::maxwell3d {
ConstantBufferSelectorState::ConstantBufferSelectorState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) : engine{manager, dirtyHandle, engine} {} 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}; 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 // 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<size_t>(minSize, selector.size), false);
}
bool ConstantBufferSelectorState::Refresh(InterconnectContext &ctx, size_t minSize) {
const auto &selector{engine->constantBufferSelector};
size_t selectorMinSize{std::max<size_t>(minSize, selector.size)};
if (view->size != selectorMinSize)
view.Update(ctx, selector.address, selectorMinSize, false);
return false;
} }
void ConstantBufferSelectorState::PurgeCaches() { void ConstantBufferSelectorState::PurgeCaches() {
@ -42,7 +51,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
} }
void ConstantBuffers::Load(InterconnectContext &ctx, span<u32> data, u32 offset) { void ConstantBuffers::Load(InterconnectContext &ctx, span<u32> data, u32 offset) {
auto &view{*selectorState.UpdateGet(ctx).view}; auto &view{*selectorState.UpdateGet(ctx, data.size_bytes()).view};
auto srcCpuBuf{data.cast<u8>()}; auto srcCpuBuf{data.cast<u8>()};
ctx.executor.AcquireBufferManager(); ctx.executor.AcquireBufferManager();
@ -79,6 +88,9 @@ namespace skyline::gpu::interconnect::maxwell3d {
void ConstantBuffers::Bind(InterconnectContext &ctx, engine::ShaderStage stage, size_t index) { void ConstantBuffers::Bind(InterconnectContext &ctx, engine::ShaderStage stage, size_t index) {
auto &view{*selectorState.UpdateGet(ctx).view}; auto &view{*selectorState.UpdateGet(ctx).view};
if (!view)
throw exception("Constant buffer selector is not mapped");
boundConstantBuffers[static_cast<size_t>(stage)][index] = {view}; boundConstantBuffers[static_cast<size_t>(stage)][index] = {view};
if (quickBindEnabled && quickBind) if (quickBindEnabled && quickBind)

View File

@ -6,7 +6,7 @@
#include "common.h" #include "common.h"
namespace skyline::gpu::interconnect::maxwell3d { namespace skyline::gpu::interconnect::maxwell3d {
class ConstantBufferSelectorState : dirty::CachedManualDirty { class ConstantBufferSelectorState : dirty::CachedManualDirty, dirty::RefreshableManualDirty {
public: public:
struct EngineRegisters { struct EngineRegisters {
const engine::ConstantBufferSelector &constantBufferSelector; const engine::ConstantBufferSelector &constantBufferSelector;
@ -22,7 +22,9 @@ namespace skyline::gpu::interconnect::maxwell3d {
CachedMappedBufferView view; CachedMappedBufferView view;
void Flush(InterconnectContext &ctx); void Flush(InterconnectContext &ctx, size_t minSize = 0);
bool Refresh(InterconnectContext &ctx, size_t minSize = 0);
void PurgeCaches(); void PurgeCaches();
}; };