mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 12:45:56 +00:00
config: Add toggle for DMA (#3185)
* config: Add toggle for DMA * config: Log new config
This commit is contained in:
parent
48460d1cbe
commit
df22c4225e
9 changed files with 52 additions and 24 deletions
|
@ -52,6 +52,7 @@ static std::string isSideTrophy = "right";
|
||||||
static bool isNullGpu = false;
|
static bool isNullGpu = false;
|
||||||
static bool shouldCopyGPUBuffers = false;
|
static bool shouldCopyGPUBuffers = false;
|
||||||
static bool readbacksEnabled = false;
|
static bool readbacksEnabled = false;
|
||||||
|
static bool directMemoryAccessEnabled = false;
|
||||||
static bool shouldDumpShaders = false;
|
static bool shouldDumpShaders = false;
|
||||||
static bool shouldPatchShaders = true;
|
static bool shouldPatchShaders = true;
|
||||||
static u32 vblankDivider = 1;
|
static u32 vblankDivider = 1;
|
||||||
|
@ -245,6 +246,10 @@ bool readbacks() {
|
||||||
return readbacksEnabled;
|
return readbacksEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool directMemoryAccess() {
|
||||||
|
return directMemoryAccessEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
bool dumpShaders() {
|
bool dumpShaders() {
|
||||||
return shouldDumpShaders;
|
return shouldDumpShaders;
|
||||||
}
|
}
|
||||||
|
@ -353,6 +358,10 @@ void setReadbacks(bool enable) {
|
||||||
readbacksEnabled = enable;
|
readbacksEnabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDirectMemoryAccess(bool enable) {
|
||||||
|
directMemoryAccessEnabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
void setDumpShaders(bool enable) {
|
void setDumpShaders(bool enable) {
|
||||||
shouldDumpShaders = enable;
|
shouldDumpShaders = enable;
|
||||||
}
|
}
|
||||||
|
@ -596,6 +605,7 @@ void load(const std::filesystem::path& path) {
|
||||||
isNullGpu = toml::find_or<bool>(gpu, "nullGpu", false);
|
isNullGpu = toml::find_or<bool>(gpu, "nullGpu", false);
|
||||||
shouldCopyGPUBuffers = toml::find_or<bool>(gpu, "copyGPUBuffers", false);
|
shouldCopyGPUBuffers = toml::find_or<bool>(gpu, "copyGPUBuffers", false);
|
||||||
readbacksEnabled = toml::find_or<bool>(gpu, "readbacks", false);
|
readbacksEnabled = toml::find_or<bool>(gpu, "readbacks", false);
|
||||||
|
directMemoryAccessEnabled = toml::find_or<bool>(gpu, "directMemoryAccess", false);
|
||||||
shouldDumpShaders = toml::find_or<bool>(gpu, "dumpShaders", false);
|
shouldDumpShaders = toml::find_or<bool>(gpu, "dumpShaders", false);
|
||||||
shouldPatchShaders = toml::find_or<bool>(gpu, "patchShaders", true);
|
shouldPatchShaders = toml::find_or<bool>(gpu, "patchShaders", true);
|
||||||
vblankDivider = toml::find_or<int>(gpu, "vblankDivider", 1);
|
vblankDivider = toml::find_or<int>(gpu, "vblankDivider", 1);
|
||||||
|
@ -746,6 +756,7 @@ void save(const std::filesystem::path& path) {
|
||||||
data["GPU"]["nullGpu"] = isNullGpu;
|
data["GPU"]["nullGpu"] = isNullGpu;
|
||||||
data["GPU"]["copyGPUBuffers"] = shouldCopyGPUBuffers;
|
data["GPU"]["copyGPUBuffers"] = shouldCopyGPUBuffers;
|
||||||
data["GPU"]["readbacks"] = readbacksEnabled;
|
data["GPU"]["readbacks"] = readbacksEnabled;
|
||||||
|
data["GPU"]["directMemoryAccess"] = directMemoryAccessEnabled;
|
||||||
data["GPU"]["dumpShaders"] = shouldDumpShaders;
|
data["GPU"]["dumpShaders"] = shouldDumpShaders;
|
||||||
data["GPU"]["patchShaders"] = shouldPatchShaders;
|
data["GPU"]["patchShaders"] = shouldPatchShaders;
|
||||||
data["GPU"]["vblankDivider"] = vblankDivider;
|
data["GPU"]["vblankDivider"] = vblankDivider;
|
||||||
|
|
|
@ -47,6 +47,8 @@ bool copyGPUCmdBuffers();
|
||||||
void setCopyGPUCmdBuffers(bool enable);
|
void setCopyGPUCmdBuffers(bool enable);
|
||||||
bool readbacks();
|
bool readbacks();
|
||||||
void setReadbacks(bool enable);
|
void setReadbacks(bool enable);
|
||||||
|
bool directMemoryAccess();
|
||||||
|
void setDirectMemoryAccess(bool enable);
|
||||||
bool dumpShaders();
|
bool dumpShaders();
|
||||||
void setDumpShaders(bool enable);
|
void setDumpShaders(bool enable);
|
||||||
u32 vblankDiv();
|
u32 vblankDiv();
|
||||||
|
|
|
@ -133,6 +133,7 @@ void Emulator::Run(std::filesystem::path file, const std::vector<std::string> ar
|
||||||
LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole());
|
LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole());
|
||||||
LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu());
|
LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu());
|
||||||
LOG_INFO(Config, "GPU readbacks: {}", Config::readbacks());
|
LOG_INFO(Config, "GPU readbacks: {}", Config::readbacks());
|
||||||
|
LOG_INFO(Config, "GPU directMemoryAccess: {}", Config::directMemoryAccess());
|
||||||
LOG_INFO(Config, "GPU shouldDumpShaders: {}", Config::dumpShaders());
|
LOG_INFO(Config, "GPU shouldDumpShaders: {}", Config::dumpShaders());
|
||||||
LOG_INFO(Config, "GPU vblankDivider: {}", Config::vblankDiv());
|
LOG_INFO(Config, "GPU vblankDivider: {}", Config::vblankDiv());
|
||||||
LOG_INFO(Config, "Vulkan gpuId: {}", Config::getGpuId());
|
LOG_INFO(Config, "Vulkan gpuId: {}", Config::getGpuId());
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/config.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "shader_recompiler/backend/spirv/emit_spirv_bounds.h"
|
#include "shader_recompiler/backend/spirv/emit_spirv_bounds.h"
|
||||||
#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h"
|
#include "shader_recompiler/backend/spirv/emit_spirv_instructions.h"
|
||||||
|
@ -167,6 +168,9 @@ using PointerSize = EmitContext::PointerSize;
|
||||||
|
|
||||||
Id EmitReadConst(EmitContext& ctx, IR::Inst* inst, Id addr, Id offset) {
|
Id EmitReadConst(EmitContext& ctx, IR::Inst* inst, Id addr, Id offset) {
|
||||||
const u32 flatbuf_off_dw = inst->Flags<u32>();
|
const u32 flatbuf_off_dw = inst->Flags<u32>();
|
||||||
|
if (!Config::directMemoryAccess()) {
|
||||||
|
return ctx.EmitFlatbufferLoad(ctx.ConstU32(flatbuf_off_dw));
|
||||||
|
}
|
||||||
// We can only provide a fallback for immediate offsets.
|
// We can only provide a fallback for immediate offsets.
|
||||||
if (flatbuf_off_dw == 0) {
|
if (flatbuf_off_dw == 0) {
|
||||||
return ctx.OpFunctionCall(ctx.U32[1], ctx.read_const_dynamic, addr, offset);
|
return ctx.OpFunctionCall(ctx.U32[1], ctx.read_const_dynamic, addr, offset);
|
||||||
|
|
|
@ -784,19 +784,6 @@ EmitContext::BufferSpv EmitContext::DefineBuffer(bool is_storage, bool is_writte
|
||||||
};
|
};
|
||||||
|
|
||||||
void EmitContext::DefineBuffers() {
|
void EmitContext::DefineBuffers() {
|
||||||
if (!profile.supports_robust_buffer_access && !info.uses_dma) {
|
|
||||||
// In case Flatbuf has not already been bound by IR and is needed
|
|
||||||
// to query buffer sizes, bind it now.
|
|
||||||
info.buffers.push_back({
|
|
||||||
.used_types = IR::Type::U32,
|
|
||||||
// We can't guarantee that flatbuf will not grow past UBO
|
|
||||||
// limit if there are a lot of ReadConsts. (We could specialize)
|
|
||||||
.inline_cbuf = AmdGpu::Buffer::Placeholder(std::numeric_limits<u32>::max()),
|
|
||||||
.buffer_type = BufferType::Flatbuf,
|
|
||||||
});
|
|
||||||
// In the future we may want to read buffer sizes from GPU memory if available.
|
|
||||||
// info.readconst_types |= Info::ReadConstType::Immediate;
|
|
||||||
}
|
|
||||||
for (const auto& desc : info.buffers) {
|
for (const auto& desc : info.buffers) {
|
||||||
const auto buf_sharp = desc.GetSharp(info);
|
const auto buf_sharp = desc.GetSharp(info);
|
||||||
const bool is_storage = desc.IsStorage(buf_sharp, profile);
|
const bool is_storage = desc.IsStorage(buf_sharp, profile);
|
||||||
|
@ -1219,14 +1206,7 @@ Id EmitContext::DefineReadConst(bool dynamic) {
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
return u32_zero_value;
|
return u32_zero_value;
|
||||||
} else {
|
} else {
|
||||||
const auto& flatbuf_buffer{buffers[flatbuf_index]};
|
return EmitFlatbufferLoad(flatbuf_offset);
|
||||||
ASSERT(flatbuf_buffer.binding >= 0 &&
|
|
||||||
flatbuf_buffer.buffer_type == BufferType::Flatbuf);
|
|
||||||
const auto [flatbuf_buffer_id, flatbuf_pointer_type] =
|
|
||||||
flatbuf_buffer.Alias(PointerType::U32);
|
|
||||||
const auto ptr{OpAccessChain(flatbuf_pointer_type, flatbuf_buffer_id, u32_zero_value,
|
|
||||||
flatbuf_offset)};
|
|
||||||
return OpLoad(U32[1], ptr);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,16 @@ public:
|
||||||
return OpAccessChain(result_type, shared_mem, index);
|
return OpAccessChain(result_type, shared_mem, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id EmitFlatbufferLoad(Id flatbuf_offset) {
|
||||||
|
const auto& flatbuf_buffer{buffers[flatbuf_index]};
|
||||||
|
ASSERT(flatbuf_buffer.binding >= 0 && flatbuf_buffer.buffer_type == BufferType::Flatbuf);
|
||||||
|
const auto [flatbuf_buffer_id, flatbuf_pointer_type] =
|
||||||
|
flatbuf_buffer.aliases[u32(PointerType::U32)];
|
||||||
|
const auto ptr{
|
||||||
|
OpAccessChain(flatbuf_pointer_type, flatbuf_buffer_id, u32_zero_value, flatbuf_offset)};
|
||||||
|
return OpLoad(U32[1], ptr);
|
||||||
|
}
|
||||||
|
|
||||||
Info& info;
|
Info& info;
|
||||||
const RuntimeInfo& runtime_info;
|
const RuntimeInfo& runtime_info;
|
||||||
const Profile& profile;
|
const Profile& profile;
|
||||||
|
|
|
@ -19,7 +19,7 @@ void ConstantPropagationPass(IR::BlockList& program);
|
||||||
void FlattenExtendedUserdataPass(IR::Program& program);
|
void FlattenExtendedUserdataPass(IR::Program& program);
|
||||||
void ReadLaneEliminationPass(IR::Program& program);
|
void ReadLaneEliminationPass(IR::Program& program);
|
||||||
void ResourceTrackingPass(IR::Program& program);
|
void ResourceTrackingPass(IR::Program& program);
|
||||||
void CollectShaderInfoPass(IR::Program& program);
|
void CollectShaderInfoPass(IR::Program& program, const Profile& profile);
|
||||||
void LowerBufferFormatToRaw(IR::Program& program);
|
void LowerBufferFormatToRaw(IR::Program& program);
|
||||||
void LowerFp64ToFp32(IR::Program& program);
|
void LowerFp64ToFp32(IR::Program& program);
|
||||||
void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtime_info);
|
void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtime_info);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/config.h"
|
||||||
#include "shader_recompiler/ir/program.h"
|
#include "shader_recompiler/ir/program.h"
|
||||||
#include "video_core/buffer_cache/buffer_cache.h"
|
#include "video_core/buffer_cache/buffer_cache.h"
|
||||||
|
|
||||||
|
@ -138,7 +139,7 @@ void Visit(Info& info, const IR::Inst& inst) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectShaderInfoPass(IR::Program& program) {
|
void CollectShaderInfoPass(IR::Program& program, const Profile& profile) {
|
||||||
auto& info = program.info;
|
auto& info = program.info;
|
||||||
for (IR::Block* const block : program.post_order_blocks) {
|
for (IR::Block* const block : program.post_order_blocks) {
|
||||||
for (IR::Inst& inst : block->Instructions()) {
|
for (IR::Inst& inst : block->Instructions()) {
|
||||||
|
@ -146,6 +147,25 @@ void CollectShaderInfoPass(IR::Program& program) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In case Flatbuf has not already been bound by IR and is needed
|
||||||
|
// to query buffer sizes, bind it now.
|
||||||
|
if (!profile.supports_robust_buffer_access && !info.uses_dma) {
|
||||||
|
info.buffers.push_back({
|
||||||
|
.used_types = IR::Type::U32,
|
||||||
|
// We can't guarantee that flatbuf will not grow past UBO
|
||||||
|
// limit if there are a lot of ReadConsts. (We could specialize)
|
||||||
|
.inline_cbuf = AmdGpu::Buffer::Placeholder(std::numeric_limits<u32>::max()),
|
||||||
|
.buffer_type = BufferType::Flatbuf,
|
||||||
|
});
|
||||||
|
// In the future we may want to read buffer sizes from GPU memory if available.
|
||||||
|
// info.readconst_types |= Info::ReadConstType::Immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Config::directMemoryAccess()) {
|
||||||
|
info.uses_dma = false;
|
||||||
|
info.readconst_types = Info::ReadConstType::None;
|
||||||
|
}
|
||||||
|
|
||||||
if (info.uses_dma) {
|
if (info.uses_dma) {
|
||||||
info.buffers.push_back({
|
info.buffers.push_back({
|
||||||
.used_types = IR::Type::U64,
|
.used_types = IR::Type::U64,
|
||||||
|
|
|
@ -84,7 +84,7 @@ IR::Program TranslateProgram(std::span<const u32> code, Pools& pools, Info& info
|
||||||
Shader::Optimization::IdentityRemovalPass(program.blocks);
|
Shader::Optimization::IdentityRemovalPass(program.blocks);
|
||||||
Shader::Optimization::DeadCodeEliminationPass(program);
|
Shader::Optimization::DeadCodeEliminationPass(program);
|
||||||
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
|
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
|
||||||
Shader::Optimization::CollectShaderInfoPass(program);
|
Shader::Optimization::CollectShaderInfoPass(program, profile);
|
||||||
|
|
||||||
Shader::IR::DumpProgram(program, info);
|
Shader::IR::DumpProgram(program, info);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue