Compare commits

..

16 Commits

Author SHA1 Message Date
FengChen
99cac846e7 video_core: Create indirect buffer instead of dynamic create 2023-02-11 16:00:59 +08:00
liamwhite
b3a8c0dc49 Merge pull request #9761 from Morph1984/oops
main: Re-add QtWebEngine zoom factor
2023-02-10 10:54:10 -05:00
bunnei
84743fd6ce Merge pull request #9765 from liamwhite/ffs-apple
kernel: avoid usage of bit_cast
2023-02-10 07:53:40 -08:00
Liam
36b70dec05 kernel: avoid usage of bit_cast 2023-02-10 09:13:58 -05:00
Morph
3fbb93e5c9 main: Re-add QtWebEngine zoom factor
For some reason, I had removed this in ad6cec71ec

This should fix any improperly scaled web applets.
2023-02-09 22:57:37 -05:00
liamwhite
c5743d5499 Merge pull request #9736 from Kelebek1/dynamic_vertex_attribs
Remove fake vertex bindings when dynamic state is enabled
2023-02-09 22:14:55 -05:00
liamwhite
cbb289fbee Merge pull request #9750 from ameerj/glsl-sample-id-mask
glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
2023-02-09 22:14:47 -05:00
liamwhite
c0b36c2d26 Merge pull request #9758 from german77/multi_audio
audio: cubeb: Fix yuzu crashing when it test for latency
2023-02-09 22:14:33 -05:00
Narr the Reg
7c0dcea96c audio: cubeb: Fix yuzu crashing when it test for latency 2023-02-09 19:38:03 -06:00
Matías Locatti
7bad3a7e5e Merge pull request #9749 from ameerj/pr9559-partial-revert
buffer_base: Partially revert changes from #9559
2023-02-09 17:53:45 -03:00
ameerj
eb9f16dce4 buffer_base: Partially revert changes from #9559
This fixes a regression where Yoshi's Crafted World (and potentially other titles) would enter an infinite loop when GPU Accuracy was set to "Normal"
2023-02-08 19:37:23 -05:00
ameerj
04139cb3ed glsl_emit_context: Remove redeclarations of gl_SampleID and gl_SampleMask
These built-ins seem to be available without needing to be declared for fragment shaders, similar i.e. to gl_FragDepth
2023-02-08 19:34:39 -05:00
liamwhite
f6477b91f9 Merge pull request #9747 from german77/SetSupportedNpadIdTypes
service: hid: Return error if arguments of SetSupportedNpadIdType is invalid
2023-02-08 10:09:26 -05:00
Mai
f3b532d091 Merge pull request #9739 from liamwhite/old-gcc-fix
kernel: fix compilation with older gcc
2023-02-07 22:10:35 -05:00
Liam
82c2a3da9f kernel: fix compilation with older gcc 2023-02-06 13:14:27 -05:00
Kelebek1
8ae2a664d2 Remove fake vertex bindings when dynamic state is enabled 2023-02-05 22:28:03 +00:00
20 changed files with 99 additions and 152 deletions

View File

@@ -302,11 +302,21 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
std::vector<std::string> device_list;
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Device Enumerator", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
return {};
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
auto type{capture ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT};
cubeb_device_collection collection;
if (cubeb_enumerate_devices(ctx, type, &collection) != CUBEB_OK) {
@@ -329,12 +339,22 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
u32 GetCubebLatency() {
cubeb* ctx;
#ifdef _WIN32
auto com_init_result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif
if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
// Return a large latency so we choose SDL instead.
return 10000u;
}
#ifdef _WIN32
if (SUCCEEDED(com_init_result)) {
CoUninitialize();
}
#endif
cubeb_stream_params params{};
params.rate = TargetSampleRate;
params.channels = 2;

View File

@@ -957,7 +957,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
raw_status.gyro.y.value,
raw_status.gyro.z.value,
});
emulated.SetUserGyroThreshold(raw_status.gyro.x.properties.threshold);
emulated.SetGyroThreshold(raw_status.gyro.x.properties.threshold);
emulated.UpdateRotation(raw_status.delta_timestamp);
emulated.UpdateOrientation(raw_status.delta_timestamp);
force_update_motion = raw_status.force_update;
@@ -1284,26 +1284,6 @@ void EmulatedController::SetLedPattern() {
}
}
void EmulatedController::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode) {
for (auto& motion : controller.motion_values) {
switch (mode) {
case GyroscopeZeroDriftMode::Loose:
motion_sensitivity = motion.emulated.IsAtRestLoose;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdLoose);
break;
case GyroscopeZeroDriftMode::Tight:
motion_sensitivity = motion.emulated.IsAtRestThight;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdThight);
break;
case GyroscopeZeroDriftMode::Standard:
default:
motion_sensitivity = motion.emulated.IsAtRestStandard;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdStandard);
break;
}
}
}
void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) {
supported_style_tag = supported_styles;
if (!is_connected) {

View File

@@ -398,9 +398,6 @@ public:
/// Asks the output device to change the player led pattern
void SetLedPattern();
/// Changes sensitivity of the motion sensor
void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode);
/**
* Adds a callback to the list of events
* @param update_callback A ConsoleUpdateCallback that will be triggered
@@ -526,7 +523,7 @@ private:
bool is_connected{false};
bool is_configuring{false};
bool system_buttons_enabled{true};
f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
f32 motion_sensitivity{0.01f};
bool force_update_motion{false};
u32 turbo_button_state{0};

View File

@@ -282,13 +282,6 @@ enum class VibrationGcErmCommand : u64 {
StopHard = 2,
};
// This is nn::hid::GyroscopeZeroDriftMode
enum class GyroscopeZeroDriftMode : u32 {
Loose = 0,
Standard = 1,
Tight = 2,
};
// This is nn::hid::NpadStyleTag
struct NpadStyleTag {
union {

View File

@@ -9,7 +9,7 @@ namespace Core::HID {
MotionInput::MotionInput() {
// Initialize PID constants with default values
SetPID(0.3f, 0.005f, 0.0f);
SetGyroThreshold(ThresholdStandard);
SetGyroThreshold(0.007f);
}
void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
@@ -26,11 +26,11 @@ void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
gyro = gyroscope - gyro_bias;
// Auto adjust drift to minimize drift
if (!IsMoving(IsAtRestRelaxed)) {
if (!IsMoving(0.1f)) {
gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
}
if (gyro.Length() < gyro_threshold * user_gyro_threshold) {
if (gyro.Length() < gyro_threshold) {
gyro = {};
} else {
only_accelerometer = false;
@@ -49,10 +49,6 @@ void MotionInput::SetGyroThreshold(f32 threshold) {
gyro_threshold = threshold;
}
void MotionInput::SetUserGyroThreshold(f32 threshold) {
user_gyro_threshold = threshold / ThresholdStandard;
}
void MotionInput::EnableReset(bool reset) {
reset_enabled = reset;
}
@@ -212,7 +208,7 @@ void MotionInput::ResetOrientation() {
if (!reset_enabled || only_accelerometer) {
return;
}
if (!IsMoving(IsAtRestRelaxed) && accel.z <= -0.9f) {
if (!IsMoving(0.5f) && accel.z <= -0.9f) {
++reset_counter;
if (reset_counter > 900) {
quat.w = 0;

View File

@@ -11,15 +11,6 @@ namespace Core::HID {
class MotionInput {
public:
static constexpr float ThresholdLoose = 0.01f;
static constexpr float ThresholdStandard = 0.007f;
static constexpr float ThresholdThight = 0.002f;
static constexpr float IsAtRestRelaxed = 0.05f;
static constexpr float IsAtRestLoose = 0.02f;
static constexpr float IsAtRestStandard = 0.01f;
static constexpr float IsAtRestThight = 0.005f;
explicit MotionInput();
MotionInput(const MotionInput&) = default;
@@ -35,9 +26,6 @@ public:
void SetGyroBias(const Common::Vec3f& bias);
void SetGyroThreshold(f32 threshold);
/// Applies a modifier on top of the normal gyro threshold
void SetUserGyroThreshold(f32 threshold);
void EnableReset(bool reset);
void ResetRotations();
@@ -86,9 +74,6 @@ private:
// Minimum gyro amplitude to detect if the device is moving
f32 gyro_threshold = 0.0f;
// Multiplies gyro_threshold by this value
f32 user_gyro_threshold = 0.0f;
// Number of invalid sequential data
u32 reset_counter = 0;

View File

@@ -203,23 +203,23 @@ Result KCapabilities::ProcessMapRegionCapability(const u32 cap, F f) {
Result KCapabilities::MapRegion_(const u32 cap, KPageTable* page_table) {
// Map each region into the process's page table.
R_RETURN(ProcessMapRegionCapability(
return ProcessMapRegionCapability(
cap, [](KMemoryRegionType region_type, KMemoryPermission perm) -> Result {
// R_RETURN(page_table->MapRegion(region_type, perm));
UNIMPLEMENTED();
R_SUCCEED();
}));
});
}
Result KCapabilities::CheckMapRegion(KernelCore& kernel, const u32 cap) {
// Check that each region has a physical backing store.
R_RETURN(ProcessMapRegionCapability(
return ProcessMapRegionCapability(
cap, [&](KMemoryRegionType region_type, KMemoryPermission perm) -> Result {
R_UNLESS(kernel.MemoryLayout().GetPhysicalMemoryRegionTree().FindFirstDerived(
region_type) != nullptr,
ResultOutOfRange);
R_SUCCEED();
}));
});
}
Result KCapabilities::SetInterruptPairCapability(const u32 cap) {

View File

@@ -3,6 +3,7 @@
#pragma once
#include <condition_variable>
#include <cstddef>
#include <memory>
#include <mutex>

View File

@@ -35,11 +35,11 @@ constexpr inline u32 EncodeKernelVersion(u32 major, u32 minor) {
}
constexpr inline u32 GetKernelMajorVersion(u32 encoded) {
return std::bit_cast<decltype(KernelVersion::major_version)>(encoded).Value();
return decltype(KernelVersion::major_version)::ExtractValue(encoded);
}
constexpr inline u32 GetKernelMinorVersion(u32 encoded) {
return std::bit_cast<decltype(KernelVersion::minor_version)>(encoded).Value();
return decltype(KernelVersion::minor_version)::ExtractValue(encoded);
}
// Nintendo doesn't support programs targeting SVC versions < 3.0.

View File

@@ -1132,8 +1132,7 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
return ResultSuccess;
}
Result Controller_NPad::SetGyroscopeZeroDriftMode(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode drift_mode) {
const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode) {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
@@ -1141,16 +1140,14 @@ Result Controller_NPad::SetGyroscopeZeroDriftMode(
}
auto& sixaxis = GetSixaxisState(sixaxis_handle);
auto& controller = GetControllerFromHandle(sixaxis_handle);
sixaxis.gyroscope_zero_drift_mode = drift_mode;
controller.device->SetGyroscopeZeroDriftMode(drift_mode);
return ResultSuccess;
}
Result Controller_NPad::GetGyroscopeZeroDriftMode(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode& drift_mode) const {
GyroscopeZeroDriftMode& drift_mode) const {
const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
if (is_valid.IsError()) {
LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);

View File

@@ -52,6 +52,13 @@ public:
// When the controller is requesting a motion update for the shared memory
void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override;
// This is nn::hid::GyroscopeZeroDriftMode
enum class GyroscopeZeroDriftMode : u32 {
Loose = 0,
Standard = 1,
Tight = 2,
};
// This is nn::hid::NpadJoyHoldType
enum class NpadJoyHoldType : u64 {
Vertical = 0,
@@ -139,9 +146,9 @@ public:
Result DisconnectNpad(Core::HID::NpadIdType npad_id);
Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode drift_mode);
GyroscopeZeroDriftMode drift_mode);
Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode& drift_mode) const;
GyroscopeZeroDriftMode& drift_mode) const;
Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
bool& is_at_rest) const;
Result IsFirmwareUpdateAvailableForSixAxisSensor(
@@ -482,8 +489,7 @@ private:
Core::HID::SixAxisSensorFusionParameters fusion{};
Core::HID::SixAxisSensorCalibrationParameter calibration{};
Core::HID::SixAxisSensorIcInformation ic_information{};
Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{
Core::HID::GyroscopeZeroDriftMode::Standard};
GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
};
struct NpadControllerData {

View File

@@ -712,7 +712,7 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()};
const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()};
const auto drift_mode{rp.PopEnum<Controller_NPad::GyroscopeZeroDriftMode>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
@@ -739,7 +739,7 @@ void Hid::GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
@@ -764,7 +764,7 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
const auto drift_mode{Controller_NPad::GyroscopeZeroDriftMode::Standard};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);

View File

@@ -310,12 +310,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
if (runtime_info.force_early_z) {
header += "layout(early_fragment_tests)in;";
}
if (info.uses_sample_id) {
header += "in int gl_SampleID;";
}
if (info.stores_sample_mask) {
header += "out int gl_SampleMask[];";
}
break;
case Stage::Compute:
stage_name = "cs";

View File

@@ -538,7 +538,7 @@ TEST_CASE("BufferBase: Cached write downloads") {
int num = 0;
buffer.ForEachDownloadRangeAndClear(c, WORD, [&](u64 offset, u64 size) { ++num; });
buffer.ForEachUploadRange(c, WORD, [&](u64 offset, u64 size) { ++num; });
REQUIRE(num == 1);
REQUIRE(num == 0);
REQUIRE(!buffer.IsRegionCpuModified(c + PAGE, PAGE));
REQUIRE(!buffer.IsRegionGpuModified(c + PAGE, PAGE));
buffer.FlushCachedWrites();

View File

@@ -289,6 +289,11 @@ public:
return cpu_addr;
}
/// Update the base CPU address of the buffer
void UpdateCpuAddr(VAddr cpu_addr_) noexcept {
cpu_addr = cpu_addr_;
}
/// Returns the offset relative to the given CPU address
/// @pre IsInBounds returns true
[[nodiscard]] u32 Offset(VAddr other_cpu_addr) const noexcept {
@@ -430,7 +435,7 @@ private:
if (query_begin >= SizeBytes() || size < 0) {
return;
}
[[maybe_unused]] u64* const untracked_words = Array<Type::Untracked>();
u64* const untracked_words = Array<Type::Untracked>();
u64* const state_words = Array<type>();
const u64 query_end = query_begin + std::min(static_cast<u64>(size), SizeBytes());
u64* const words_begin = state_words + query_begin / BYTES_PER_WORD;
@@ -483,7 +488,7 @@ private:
NotifyRasterizer<true>(word_index, current_bits, ~u64{0});
}
// Exclude CPU modified pages when visiting GPU pages
const u64 word = current_word;
const u64 word = current_word & ~(type == Type::GPU ? untracked_words[word_index] : 0);
u64 page = page_begin;
page_begin = 0;
@@ -531,7 +536,7 @@ private:
[[nodiscard]] bool IsRegionModified(u64 offset, u64 size) const noexcept {
static_assert(type != Type::Untracked);
[[maybe_unused]] const u64* const untracked_words = Array<Type::Untracked>();
const u64* const untracked_words = Array<Type::Untracked>();
const u64* const state_words = Array<type>();
const u64 num_query_words = size / BYTES_PER_WORD + 1;
const u64 word_begin = offset / BYTES_PER_WORD;
@@ -539,7 +544,8 @@ private:
const u64 page_limit = Common::DivCeil(offset + size, BYTES_PER_PAGE);
u64 page_index = (offset / BYTES_PER_PAGE) % PAGES_PER_WORD;
for (u64 word_index = word_begin; word_index < word_end; ++word_index, page_index = 0) {
const u64 word = state_words[word_index];
const u64 off_word = type == Type::GPU ? untracked_words[word_index] : 0;
const u64 word = state_words[word_index] & ~off_word;
if (word == 0) {
continue;
}
@@ -563,7 +569,7 @@ private:
[[nodiscard]] std::pair<u64, u64> ModifiedRegion(u64 offset, u64 size) const noexcept {
static_assert(type != Type::Untracked);
[[maybe_unused]] const u64* const untracked_words = Array<Type::Untracked>();
const u64* const untracked_words = Array<Type::Untracked>();
const u64* const state_words = Array<type>();
const u64 num_query_words = size / BYTES_PER_WORD + 1;
const u64 word_begin = offset / BYTES_PER_WORD;
@@ -573,7 +579,8 @@ private:
u64 begin = std::numeric_limits<u64>::max();
u64 end = 0;
for (u64 word_index = word_begin; word_index < word_end; ++word_index) {
const u64 word = state_words[word_index];
const u64 off_word = type == Type::GPU ? untracked_words[word_index] : 0;
const u64 word = state_words[word_index] & ~off_word;
if (word == 0) {
continue;
}

View File

@@ -205,9 +205,9 @@ public:
current_draw_indirect = current_draw_indirect_;
}
[[nodiscard]] std::pair<Buffer*, u32> GetDrawIndirectCount();
[[nodiscard]] typename BufferCache<P>::Buffer* GetDrawIndirectCount();
[[nodiscard]] std::pair<Buffer*, u32> GetDrawIndirectBuffer();
[[nodiscard]] typename BufferCache<P>::Buffer* GetDrawIndirectBuffer();
std::recursive_mutex mutex;
Runtime& runtime;
@@ -385,6 +385,9 @@ private:
SlotVector<Buffer> slot_buffers;
DelayedDestructionRing<Buffer, 8> delayed_destruction_ring;
Buffer indirect_buffer;
Buffer indirect_count_buffer;
const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{};
u32 last_index_count = 0;
@@ -458,7 +461,9 @@ private:
template <class P>
BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
Core::Memory::Memory& cpu_memory_, Runtime& runtime_)
: runtime{runtime_}, rasterizer{rasterizer_}, cpu_memory{cpu_memory_} {
: runtime{runtime_}, rasterizer{rasterizer_}, cpu_memory{cpu_memory_},
indirect_buffer(runtime, rasterizer, 0, 0x1000),
indirect_count_buffer(runtime, rasterizer, 0, 0x1000) {
// Ensure the first slot is used for the null buffer
void(slot_buffers.insert(runtime, NullBufferParams{}));
common_ranges.clear();
@@ -1064,15 +1069,13 @@ void BufferCache<P>::BindHostVertexBuffers() {
template <class P>
void BufferCache<P>::BindHostDrawIndirectBuffers() {
const auto bind_buffer = [this](const Binding& binding) {
Buffer& buffer = slot_buffers[binding.buffer_id];
TouchBuffer(buffer, binding.buffer_id);
const auto bind_buffer = [this](const Binding& binding, Buffer& buffer) {
SynchronizeBuffer(buffer, binding.cpu_addr, binding.size);
};
if (current_draw_indirect->include_count) {
bind_buffer(count_buffer_binding);
bind_buffer(count_buffer_binding, indirect_count_buffer);
}
bind_buffer(indirect_buffer_binding);
bind_buffer(indirect_buffer_binding, indirect_buffer);
}
template <class P>
@@ -1409,14 +1412,16 @@ void BufferCache<P>::UpdateDrawIndirect() {
binding = Binding{
.cpu_addr = *cpu_addr,
.size = static_cast<u32>(size),
.buffer_id = FindBuffer(*cpu_addr, static_cast<u32>(size)),
.buffer_id = NULL_BUFFER_ID,
};
};
if (current_draw_indirect->include_count) {
update(current_draw_indirect->count_start_address, sizeof(u32), count_buffer_binding);
indirect_count_buffer.UpdateCpuAddr(count_buffer_binding.cpu_addr);
}
update(current_draw_indirect->indirect_start_address, current_draw_indirect->buffer_size,
indirect_buffer_binding);
indirect_buffer.UpdateCpuAddr(indirect_buffer_binding.cpu_addr);
}
template <class P>
@@ -2007,15 +2012,13 @@ bool BufferCache<P>::HasFastUniformBufferBound(size_t stage, u32 binding_index)
}
template <class P>
std::pair<typename BufferCache<P>::Buffer*, u32> BufferCache<P>::GetDrawIndirectCount() {
auto& buffer = slot_buffers[count_buffer_binding.buffer_id];
return std::make_pair(&buffer, buffer.Offset(count_buffer_binding.cpu_addr));
typename BufferCache<P>::Buffer* BufferCache<P>::GetDrawIndirectCount() {
return &indirect_count_buffer;
}
template <class P>
std::pair<typename BufferCache<P>::Buffer*, u32> BufferCache<P>::GetDrawIndirectBuffer() {
auto& buffer = slot_buffers[indirect_buffer_binding.buffer_id];
return std::make_pair(&buffer, buffer.Offset(indirect_buffer_binding.cpu_addr));
typename BufferCache<P>::Buffer* BufferCache<P>::GetDrawIndirectBuffer() {
return &indirect_buffer;
}
} // namespace VideoCommon

View File

@@ -285,23 +285,19 @@ void RasterizerOpenGL::DrawIndirect() {
const auto& params = maxwell3d->draw_manager->GetIndirectParams();
buffer_cache.SetDrawIndirect(&params);
PrepareDraw(params.is_indexed, [this, &params](GLenum primitive_mode) {
const auto [buffer, offset] = buffer_cache.GetDrawIndirectBuffer();
const GLvoid* const gl_offset =
reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(offset));
const auto buffer = buffer_cache.GetDrawIndirectBuffer();
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->Handle());
if (params.include_count) {
const auto [draw_buffer, offset_base] = buffer_cache.GetDrawIndirectCount();
const auto draw_buffer = buffer_cache.GetDrawIndirectCount();
glBindBuffer(GL_PARAMETER_BUFFER, draw_buffer->Handle());
if (params.is_indexed) {
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
glMultiDrawElementsIndirectCount(primitive_mode, format, gl_offset,
static_cast<GLintptr>(offset_base),
glMultiDrawElementsIndirectCount(primitive_mode, format, nullptr, 0,
static_cast<GLsizei>(params.max_draw_counts),
static_cast<GLsizei>(params.stride));
} else {
glMultiDrawArraysIndirectCount(primitive_mode, gl_offset,
static_cast<GLintptr>(offset_base),
glMultiDrawArraysIndirectCount(primitive_mode, nullptr, 0,
static_cast<GLsizei>(params.max_draw_counts),
static_cast<GLsizei>(params.stride));
}
@@ -309,11 +305,11 @@ void RasterizerOpenGL::DrawIndirect() {
}
if (params.is_indexed) {
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
glMultiDrawElementsIndirect(primitive_mode, format, gl_offset,
glMultiDrawElementsIndirect(primitive_mode, format, nullptr,
static_cast<GLsizei>(params.max_draw_counts),
static_cast<GLsizei>(params.stride));
} else {
glMultiDrawArraysIndirect(primitive_mode, gl_offset,
glMultiDrawArraysIndirect(primitive_mode, nullptr,
static_cast<GLsizei>(params.max_draw_counts),
static_cast<GLsizei>(params.stride));
}

View File

@@ -548,31 +548,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
static_vector<VkVertexInputBindingDescription, 32> vertex_bindings;
static_vector<VkVertexInputBindingDivisorDescriptionEXT, 32> vertex_binding_divisors;
static_vector<VkVertexInputAttributeDescription, 32> vertex_attributes;
if (key.state.dynamic_vertex_input) {
const size_t num_vertex_arrays = std::min(
key.state.attributes.size(), static_cast<size_t>(device.GetMaxVertexInputBindings()));
for (size_t index = 0; index < num_vertex_arrays; ++index) {
const u32 type = key.state.DynamicAttributeType(index);
if (!stage_infos[0].loads.Generic(index) || type == 0) {
continue;
}
vertex_attributes.push_back({
.location = static_cast<u32>(index),
.binding = 0,
.format = type == 1 ? VK_FORMAT_R32_SFLOAT
: type == 2 ? VK_FORMAT_R32_SINT
: VK_FORMAT_R32_UINT,
.offset = 0,
});
}
if (!vertex_attributes.empty()) {
vertex_bindings.push_back({
.binding = 0,
.stride = 4,
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
});
}
} else {
if (!key.state.dynamic_vertex_input) {
const size_t num_vertex_arrays = std::min(
Maxwell::NumVertexArrays, static_cast<size_t>(device.GetMaxVertexInputBindings()));
for (size_t index = 0; index < num_vertex_arrays; ++index) {

View File

@@ -230,35 +230,29 @@ void RasterizerVulkan::DrawIndirect() {
const auto& params = maxwell3d->draw_manager->GetIndirectParams();
buffer_cache.SetDrawIndirect(&params);
PrepareDraw(params.is_indexed, [this, &params] {
const auto indirect_buffer = buffer_cache.GetDrawIndirectBuffer();
const auto& buffer = indirect_buffer.first;
const auto& offset = indirect_buffer.second;
const auto buffer = buffer_cache.GetDrawIndirectBuffer();
if (params.include_count) {
const auto count = buffer_cache.GetDrawIndirectCount();
const auto& draw_buffer = count.first;
const auto& offset_base = count.second;
const auto draw_buffer = buffer_cache.GetDrawIndirectCount();
scheduler.Record([draw_buffer_obj = draw_buffer->Handle(),
buffer_obj = buffer->Handle(), offset_base, offset,
params](vk::CommandBuffer cmdbuf) {
buffer_obj = buffer->Handle(), params](vk::CommandBuffer cmdbuf) {
if (params.is_indexed) {
cmdbuf.DrawIndexedIndirectCount(
buffer_obj, offset, draw_buffer_obj, offset_base,
static_cast<u32>(params.max_draw_counts), static_cast<u32>(params.stride));
cmdbuf.DrawIndexedIndirectCount(buffer_obj, 0, draw_buffer_obj, 0,
static_cast<u32>(params.max_draw_counts),
static_cast<u32>(params.stride));
} else {
cmdbuf.DrawIndirectCount(buffer_obj, offset, draw_buffer_obj, offset_base,
cmdbuf.DrawIndirectCount(buffer_obj, 0, draw_buffer_obj, 0,
static_cast<u32>(params.max_draw_counts),
static_cast<u32>(params.stride));
}
});
return;
}
scheduler.Record([buffer_obj = buffer->Handle(), offset, params](vk::CommandBuffer cmdbuf) {
scheduler.Record([buffer_obj = buffer->Handle(), params](vk::CommandBuffer cmdbuf) {
if (params.is_indexed) {
cmdbuf.DrawIndexedIndirect(buffer_obj, offset,
static_cast<u32>(params.max_draw_counts),
cmdbuf.DrawIndexedIndirect(buffer_obj, 0, static_cast<u32>(params.max_draw_counts),
static_cast<u32>(params.stride));
} else {
cmdbuf.DrawIndirect(buffer_obj, offset, static_cast<u32>(params.max_draw_counts),
cmdbuf.DrawIndirect(buffer_obj, 0, static_cast<u32>(params.max_draw_counts),
static_cast<u32>(params.stride));
}
});

View File

@@ -805,6 +805,8 @@ void GMainWindow::WebBrowserOpenWebPage(const std::string& main_url,
layout.screen.GetHeight() / scale_ratio);
web_browser_view.move(layout.screen.left / scale_ratio,
(layout.screen.top / scale_ratio) + menuBar()->height());
web_browser_view.setZoomFactor(static_cast<qreal>(layout.screen.GetWidth() / scale_ratio) /
static_cast<qreal>(Layout::ScreenUndocked::Width));
web_browser_view.setFocus();
web_browser_view.show();