mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-21 12:04:45 +00:00
Merge branch 'main' of https://github.com/lzardy/shadPS4
This commit is contained in:
commit
600e1bc888
13 changed files with 90 additions and 8 deletions
|
@ -124,6 +124,10 @@ bool vkValidationGpuEnabled() {
|
|||
return vkValidationGpu;
|
||||
}
|
||||
|
||||
void setGpuId(s32 selectedGpuId) {
|
||||
gpuId = selectedGpuId;
|
||||
}
|
||||
|
||||
void setScreenWidth(u32 width) {
|
||||
screenWidth = width;
|
||||
}
|
||||
|
@ -451,6 +455,7 @@ void setDefaultValues() {
|
|||
vkValidation = false;
|
||||
rdocEnable = false;
|
||||
m_language = 1;
|
||||
gpuId = -1;
|
||||
}
|
||||
|
||||
} // namespace Config
|
||||
|
|
|
@ -36,6 +36,7 @@ void setNullGpu(bool enable);
|
|||
void setDumpShaders(bool enable);
|
||||
void setDumpPM4(bool enable);
|
||||
void setVblankDiv(u32 value);
|
||||
void setGpuId(s32 selectedGpuId);
|
||||
void setScreenWidth(u32 width);
|
||||
void setScreenHeight(u32 height);
|
||||
void setFullscreenMode(bool enable);
|
||||
|
|
|
@ -360,7 +360,6 @@ int PS4_SYSV_ABI posix_connect() {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI _sigprocmask() {
|
||||
LOG_DEBUG(Lib_Kernel, "STUBBED");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "game_install_dialog.h"
|
||||
#include "main_window.h"
|
||||
#include "settings_dialog.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
|
||||
ui->setupUi(this);
|
||||
|
@ -39,6 +40,7 @@ bool MainWindow::Init() {
|
|||
CreateConnects();
|
||||
SetLastUsedTheme();
|
||||
SetLastIconSizeBullet();
|
||||
GetPhysicalDevices();
|
||||
// show ui
|
||||
setMinimumSize(350, minimumSizeHint().height());
|
||||
setWindowTitle(QString::fromStdString("shadPS4 v" + std::string(Common::VERSION)));
|
||||
|
@ -158,6 +160,19 @@ void MainWindow::LoadGameLists() {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::GetPhysicalDevices() {
|
||||
Vulkan::Instance instance(false, false);
|
||||
auto physical_devices = instance.GetPhysicalDevices();
|
||||
for (const vk::PhysicalDevice physical_device : physical_devices) {
|
||||
auto prop = physical_device.getProperties();
|
||||
QString name = QString::fromUtf8(prop.deviceName, -1);
|
||||
if (prop.apiVersion < Vulkan::TargetVulkanApiVersion) {
|
||||
name += " * Unsupported Vulkan Version";
|
||||
}
|
||||
m_physical_devices.push_back(name);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::CreateConnects() {
|
||||
connect(this, &MainWindow::WindowResized, this, &MainWindow::HandleResize);
|
||||
connect(ui->mw_searchbar, &QLineEdit::textChanged, this, &MainWindow::SearchGameTable);
|
||||
|
@ -187,7 +202,7 @@ void MainWindow::CreateConnects() {
|
|||
&MainWindow::StartGame);
|
||||
|
||||
connect(ui->settingsButton, &QPushButton::clicked, this, [this]() {
|
||||
auto settingsDialog = new SettingsDialog(this);
|
||||
auto settingsDialog = new SettingsDialog(m_physical_devices, this);
|
||||
settingsDialog->exec();
|
||||
});
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ private:
|
|||
void CreateActions();
|
||||
void CreateRecentGameActions();
|
||||
void CreateDockWindows();
|
||||
void GetPhysicalDevices();
|
||||
void LoadGameLists();
|
||||
void CreateConnects();
|
||||
void SetLastUsedTheme();
|
||||
|
@ -79,6 +80,8 @@ private:
|
|||
QScopedPointer<ElfViewer> m_elf_viewer;
|
||||
// Status Bar.
|
||||
QScopedPointer<QStatusBar> statusBar;
|
||||
// Available GPU devices
|
||||
std::vector<QString> m_physical_devices;
|
||||
|
||||
PSF psf;
|
||||
|
||||
|
|
|
@ -4,13 +4,20 @@
|
|||
#include "settings_dialog.h"
|
||||
#include "ui_settings_dialog.h"
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::SettingsDialog) {
|
||||
SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidget* parent)
|
||||
: QDialog(parent), ui(new Ui::SettingsDialog) {
|
||||
ui->setupUi(this);
|
||||
ui->tabWidgetSettings->setUsesScrollButtons(false);
|
||||
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||
|
||||
ui->buttonBox->button(QDialogButtonBox::StandardButton::Close)->setFocus();
|
||||
|
||||
// Add list of available GPUs
|
||||
ui->graphicsAdapterBox->addItem("Auto Select"); // -1, auto selection
|
||||
for (const auto& device : physical_devices) {
|
||||
ui->graphicsAdapterBox->addItem(device);
|
||||
}
|
||||
|
||||
LoadValuesFromConfig();
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close);
|
||||
|
@ -40,7 +47,10 @@ SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Se
|
|||
|
||||
// GPU TAB
|
||||
{
|
||||
// TODO: Implement graphics device changing
|
||||
// First options is auto selection -1, so gpuId on the GUI will always have to subtract 1
|
||||
// when setting and add 1 when getting to select the correct gpu in Qt
|
||||
connect(ui->graphicsAdapterBox, &QComboBox::currentIndexChanged, this,
|
||||
[](int index) { Config::setGpuId(index - 1); });
|
||||
|
||||
connect(ui->widthSpinBox, &QSpinBox::valueChanged, this,
|
||||
[](int val) { Config::setScreenWidth(val); });
|
||||
|
@ -98,6 +108,7 @@ SettingsDialog::SettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Se
|
|||
void SettingsDialog::LoadValuesFromConfig() {
|
||||
ui->consoleLanguageComboBox->setCurrentIndex(Config::GetLanguage());
|
||||
|
||||
ui->graphicsAdapterBox->setCurrentIndex(Config::getGpuId() + 1);
|
||||
ui->widthSpinBox->setValue(Config::getScreenWidth());
|
||||
ui->heightSpinBox->setValue(Config::getScreenHeight());
|
||||
ui->vblankSpinBox->setValue(Config::vblankDiv());
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include <QDialog>
|
||||
#include <QPushButton>
|
||||
|
||||
|
@ -16,7 +17,7 @@ class SettingsDialog;
|
|||
class SettingsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SettingsDialog(QWidget* parent = nullptr);
|
||||
explicit SettingsDialog(std::span<const QString> physical_devices, QWidget* parent = nullptr);
|
||||
~SettingsDialog();
|
||||
|
||||
int exec() override;
|
||||
|
|
|
@ -162,7 +162,7 @@ T Translator::GetSrc(const InstOperand& operand) {
|
|||
}
|
||||
} else {
|
||||
if (operand.input_modifier.abs) {
|
||||
UNREACHABLE();
|
||||
LOG_WARNING(Render_Vulkan, "Input abs modifier on integer instruction");
|
||||
}
|
||||
if (operand.input_modifier.neg) {
|
||||
UNREACHABLE();
|
||||
|
|
|
@ -494,6 +494,13 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
const auto tsharp = TrackSharp(tsharp_handle);
|
||||
const auto image = info.ReadUd<AmdGpu::Image>(tsharp.sgpr_base, tsharp.dword_offset);
|
||||
const auto inst_info = inst.Flags<IR::TextureInstInfo>();
|
||||
if (!image.Valid()) {
|
||||
LOG_ERROR(Render_Vulkan, "Shader compiled with unbound image!");
|
||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
||||
inst.ReplaceUsesWith(
|
||||
ir.CompositeConstruct(ir.Imm32(0.f), ir.Imm32(0.f), ir.Imm32(0.f), ir.Imm32(0.f)));
|
||||
return;
|
||||
}
|
||||
ASSERT(image.GetType() != AmdGpu::ImageType::Invalid);
|
||||
u32 image_binding = descriptors.Add(ImageResource{
|
||||
.sgpr_base = tsharp.sgpr_base,
|
||||
|
|
|
@ -408,7 +408,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||
}
|
||||
case PM4ItOpcode::WaitRegMem: {
|
||||
const auto* wait_reg_mem = reinterpret_cast<const PM4CmdWaitRegMem*>(header);
|
||||
ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me);
|
||||
// ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me);
|
||||
// Optimization: VO label waits are special because the emulator
|
||||
// will write to the label when presentation is finished. So if
|
||||
// there are no other submits to yield to we can sleep the thread
|
||||
|
|
|
@ -867,6 +867,33 @@ struct Liverpool {
|
|||
}
|
||||
};
|
||||
|
||||
union ShaderStageEnable {
|
||||
u32 raw;
|
||||
BitField<0, 2, u32> ls_en;
|
||||
BitField<2, 1, u32> hs_en;
|
||||
BitField<3, 2, u32> es_en;
|
||||
BitField<5, 1, u32> gs_en;
|
||||
BitField<6, 1, u32> vs_en;
|
||||
|
||||
bool IsStageEnabled(u32 stage) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
case 1:
|
||||
return true;
|
||||
case 2:
|
||||
return gs_en.Value();
|
||||
case 3:
|
||||
return es_en.Value();
|
||||
case 4:
|
||||
return hs_en.Value();
|
||||
case 5:
|
||||
return ls_en.Value();
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
union Regs {
|
||||
struct {
|
||||
INSERT_PADDING_WORDS(0x2C08);
|
||||
|
@ -945,7 +972,9 @@ struct Liverpool {
|
|||
INSERT_PADDING_WORDS(0xA2A8 - 0xA2A1 - 1);
|
||||
u32 vgt_instance_step_rate_0;
|
||||
u32 vgt_instance_step_rate_1;
|
||||
INSERT_PADDING_WORDS(0xA2DF - 0xA2A9 - 1);
|
||||
INSERT_PADDING_WORDS(0xA2D5 - 0xA2A9 - 1);
|
||||
ShaderStageEnable stage_enable;
|
||||
INSERT_PADDING_WORDS(9);
|
||||
PolygonOffset poly_offset;
|
||||
INSERT_PADDING_WORDS(0xA2F8 - 0xA2DF - 5);
|
||||
AaConfig aa_config;
|
||||
|
@ -1140,6 +1169,7 @@ static_assert(GFX6_3D_REG_INDEX(index_buffer_type) == 0xA29F);
|
|||
static_assert(GFX6_3D_REG_INDEX(enable_primitive_id) == 0xA2A1);
|
||||
static_assert(GFX6_3D_REG_INDEX(vgt_instance_step_rate_0) == 0xA2A8);
|
||||
static_assert(GFX6_3D_REG_INDEX(vgt_instance_step_rate_1) == 0xA2A9);
|
||||
static_assert(GFX6_3D_REG_INDEX(stage_enable) == 0xA2D5);
|
||||
static_assert(GFX6_3D_REG_INDEX(poly_offset) == 0xA2DF);
|
||||
static_assert(GFX6_3D_REG_INDEX(aa_config) == 0xA2F8);
|
||||
static_assert(GFX6_3D_REG_INDEX(color_buffers[0].base_address) == 0xA318);
|
||||
|
|
|
@ -81,6 +81,8 @@ vk::PrimitiveTopology PrimitiveType(Liverpool::PrimitiveType type) {
|
|||
return vk::PrimitiveTopology::eTriangleListWithAdjacency;
|
||||
case Liverpool::PrimitiveType::AdjTriangleStrip:
|
||||
return vk::PrimitiveTopology::eTriangleStripWithAdjacency;
|
||||
case Liverpool::PrimitiveType::PatchPrimitive:
|
||||
return vk::PrimitiveTopology::ePatchList;
|
||||
case Liverpool::PrimitiveType::QuadList:
|
||||
// Needs to generate index buffer on the fly.
|
||||
return vk::PrimitiveTopology::eTriangleList;
|
||||
|
|
|
@ -115,6 +115,10 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
|
|||
}
|
||||
|
||||
const GraphicsPipeline* PipelineCache::GetGraphicsPipeline() {
|
||||
// Tessellation is unsupported so skip the draw to avoid locking up the driver.
|
||||
if (liverpool->regs.primitive_type == Liverpool::PrimitiveType::PatchPrimitive) {
|
||||
return nullptr;
|
||||
}
|
||||
RefreshGraphicsKey();
|
||||
const auto [it, is_new] = graphics_pipelines.try_emplace(graphics_key);
|
||||
if (is_new) {
|
||||
|
@ -203,6 +207,10 @@ void PipelineCache::RefreshGraphicsKey() {
|
|||
}
|
||||
|
||||
for (u32 i = 0; i < MaxShaderStages; i++) {
|
||||
if (!regs.stage_enable.IsStageEnabled(i)) {
|
||||
key.stage_hashes[i] = 0;
|
||||
continue;
|
||||
}
|
||||
auto* pgm = regs.ProgramForStage(i);
|
||||
if (!pgm || !pgm->Address<u32*>()) {
|
||||
key.stage_hashes[i] = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue