diff options
| -rw-r--r-- | src/audio_core/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | src/audio_core/codec.cpp | 5 | ||||
| -rw-r--r-- | src/audio_core/codec.h | 2 | ||||
| -rw-r--r-- | src/audio_core/command_generator.cpp | 17 | ||||
| -rw-r--r-- | src/audio_core/cubeb_sink.cpp | 4 | ||||
| -rw-r--r-- | src/audio_core/effect_context.cpp | 8 | ||||
| -rw-r--r-- | src/audio_core/effect_context.h | 33 | ||||
| -rw-r--r-- | src/audio_core/info_updater.cpp | 7 | ||||
| -rw-r--r-- | src/audio_core/mix_context.cpp | 4 | ||||
| -rw-r--r-- | src/audio_core/splitter_context.cpp | 6 | ||||
| -rw-r--r-- | src/audio_core/voice_context.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | 70 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | 52 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | 74 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_vic.h | 63 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_stream_buffer.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/shader/registry.cpp | 50 | ||||
| -rw-r--r-- | src/video_core/shader/registry.h | 2 |
18 files changed, 339 insertions, 75 deletions
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index cb00ef60e..6a7075f73 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt | |||
| @@ -44,6 +44,16 @@ add_library(audio_core STATIC | |||
| 44 | 44 | ||
| 45 | create_target_directory_groups(audio_core) | 45 | create_target_directory_groups(audio_core) |
| 46 | 46 | ||
| 47 | if (NOT MSVC) | ||
| 48 | target_compile_options(audio_core PRIVATE | ||
| 49 | -Werror=ignored-qualifiers | ||
| 50 | -Werror=implicit-fallthrough | ||
| 51 | -Werror=reorder | ||
| 52 | -Werror=sign-compare | ||
| 53 | -Werror=unused-variable | ||
| 54 | ) | ||
| 55 | endif() | ||
| 56 | |||
| 47 | target_link_libraries(audio_core PUBLIC common core) | 57 | target_link_libraries(audio_core PUBLIC common core) |
| 48 | target_link_libraries(audio_core PRIVATE SoundTouch) | 58 | target_link_libraries(audio_core PRIVATE SoundTouch) |
| 49 | 59 | ||
diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp index c5a0d98ce..2fb91c13a 100644 --- a/src/audio_core/codec.cpp +++ b/src/audio_core/codec.cpp | |||
| @@ -16,8 +16,9 @@ std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM | |||
| 16 | 16 | ||
| 17 | constexpr std::size_t FRAME_LEN = 8; | 17 | constexpr std::size_t FRAME_LEN = 8; |
| 18 | constexpr std::size_t SAMPLES_PER_FRAME = 14; | 18 | constexpr std::size_t SAMPLES_PER_FRAME = 14; |
| 19 | constexpr std::array<int, 16> SIGNED_NIBBLES = { | 19 | static constexpr std::array<int, 16> SIGNED_NIBBLES{ |
| 20 | {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; | 20 | 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1, |
| 21 | }; | ||
| 21 | 22 | ||
| 22 | const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; | 23 | const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; |
| 23 | const std::size_t ret_size = | 24 | const std::size_t ret_size = |
diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h index ef2ce01a8..9507abb1b 100644 --- a/src/audio_core/codec.h +++ b/src/audio_core/codec.h | |||
| @@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array<s16, 16>; | |||
| 38 | * @param state ADPCM state, this is updated with new state | 38 | * @param state ADPCM state, this is updated with new state |
| 39 | * @return Decoded stereo signed PCM16 data, sample_count in length | 39 | * @return Decoded stereo signed PCM16 data, sample_count in length |
| 40 | */ | 40 | */ |
| 41 | std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff, | 41 | std::vector<s16> DecodeADPCM(const u8* data, std::size_t size, const ADPCM_Coeff& coeff, |
| 42 | ADPCMState& state); | 42 | ADPCMState& state); |
| 43 | 43 | ||
| 44 | }; // namespace AudioCore::Codec | 44 | }; // namespace AudioCore::Codec |
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index 8f7da49e6..bba40d13d 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp | |||
| @@ -152,7 +152,7 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) { | |||
| 152 | if (!destination_data->IsConfigured()) { | 152 | if (!destination_data->IsConfigured()) { |
| 153 | continue; | 153 | continue; |
| 154 | } | 154 | } |
| 155 | if (destination_data->GetMixId() >= mix_context.GetCount()) { | 155 | if (destination_data->GetMixId() >= static_cast<int>(mix_context.GetCount())) { |
| 156 | continue; | 156 | continue; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| @@ -435,7 +435,7 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf | |||
| 435 | GetMixBuffer(output_index), worker_params.sample_count, offset, write_count); | 435 | GetMixBuffer(output_index), worker_params.sample_count, offset, write_count); |
| 436 | memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); | 436 | memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); |
| 437 | 437 | ||
| 438 | if (samples_read != worker_params.sample_count && | 438 | if (samples_read != static_cast<int>(worker_params.sample_count) && |
| 439 | samples_read <= params.sample_count) { | 439 | samples_read <= params.sample_count) { |
| 440 | std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read); | 440 | std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read); |
| 441 | } | 441 | } |
| @@ -611,7 +611,8 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) { | |||
| 611 | const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId()); | 611 | const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId()); |
| 612 | const auto& dest_in_params = dest_mix.GetInParams(); | 612 | const auto& dest_in_params = dest_mix.GetInParams(); |
| 613 | const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset; | 613 | const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset; |
| 614 | for (std::size_t i = 0; i < dest_in_params.buffer_count; i++) { | 614 | for (std::size_t i = 0; i < static_cast<std::size_t>(dest_in_params.buffer_count); |
| 615 | i++) { | ||
| 615 | const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i); | 616 | const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i); |
| 616 | if (mixed_volume != 0.0f) { | 617 | if (mixed_volume != 0.0f) { |
| 617 | GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume, | 618 | GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume, |
| @@ -704,7 +705,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s | |||
| 704 | std::vector<s16> buffer(samples_processed * channel_count); | 705 | std::vector<s16> buffer(samples_processed * channel_count); |
| 705 | memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); | 706 | memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); |
| 706 | 707 | ||
| 707 | for (std::size_t i = 0; i < samples_processed; i++) { | 708 | for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) { |
| 708 | sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; | 709 | sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; |
| 709 | } | 710 | } |
| 710 | } | 711 | } |
| @@ -726,8 +727,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s | |||
| 726 | return 0; | 727 | return 0; |
| 727 | } | 728 | } |
| 728 | 729 | ||
| 729 | constexpr std::array<int, 16> SIGNED_NIBBLES = { | 730 | static constexpr std::array<int, 16> SIGNED_NIBBLES{ |
| 730 | {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; | 731 | 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1, |
| 732 | }; | ||
| 731 | 733 | ||
| 732 | constexpr std::size_t FRAME_LEN = 8; | 734 | constexpr std::size_t FRAME_LEN = 8; |
| 733 | constexpr std::size_t NIBBLES_PER_SAMPLE = 16; | 735 | constexpr std::size_t NIBBLES_PER_SAMPLE = 16; |
| @@ -789,7 +791,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s | |||
| 789 | position_in_frame += 2; | 791 | position_in_frame += 2; |
| 790 | 792 | ||
| 791 | // Decode entire frame | 793 | // Decode entire frame |
| 792 | if (remaining_samples >= SAMPLES_PER_FRAME) { | 794 | if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) { |
| 793 | for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) { | 795 | for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) { |
| 794 | 796 | ||
| 795 | // Sample 1 | 797 | // Sample 1 |
| @@ -866,7 +868,6 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o | |||
| 866 | const auto resample_rate = static_cast<s32>( | 868 | const auto resample_rate = static_cast<s32>( |
| 867 | static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) * | 869 | static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) * |
| 868 | static_cast<float>(static_cast<s32>(in_params.pitch * 32768.0f))); | 870 | static_cast<float>(static_cast<s32>(in_params.pitch * 32768.0f))); |
| 869 | auto* output_base = output; | ||
| 870 | if (dsp_state.fraction + sample_count * resample_rate > | 871 | if (dsp_state.fraction + sample_count * resample_rate > |
| 871 | static_cast<s32>(SCALED_MIX_BUFFER_SIZE - 4ULL)) { | 872 | static_cast<s32>(SCALED_MIX_BUFFER_SIZE - 4ULL)) { |
| 872 | return; | 873 | return; |
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 83c06c0ed..eb82791f6 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp | |||
| @@ -192,8 +192,8 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels, | |||
| 192 | 192 | ||
| 193 | long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, | 193 | long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, |
| 194 | void* output_buffer, long num_frames) { | 194 | void* output_buffer, long num_frames) { |
| 195 | CubebSinkStream* impl = static_cast<CubebSinkStream*>(user_data); | 195 | auto* impl = static_cast<CubebSinkStream*>(user_data); |
| 196 | u8* buffer = reinterpret_cast<u8*>(output_buffer); | 196 | auto* buffer = static_cast<u8*>(output_buffer); |
| 197 | 197 | ||
| 198 | if (!impl) { | 198 | if (!impl) { |
| 199 | return {}; | 199 | return {}; |
diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp index adfec3df5..4d9cdf524 100644 --- a/src/audio_core/effect_context.cpp +++ b/src/audio_core/effect_context.cpp | |||
| @@ -184,19 +184,19 @@ void EffectAuxInfo::UpdateForCommandGeneration() { | |||
| 184 | } | 184 | } |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | const VAddr EffectAuxInfo::GetSendInfo() const { | 187 | VAddr EffectAuxInfo::GetSendInfo() const { |
| 188 | return send_info; | 188 | return send_info; |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | const VAddr EffectAuxInfo::GetSendBuffer() const { | 191 | VAddr EffectAuxInfo::GetSendBuffer() const { |
| 192 | return send_buffer; | 192 | return send_buffer; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | const VAddr EffectAuxInfo::GetRecvInfo() const { | 195 | VAddr EffectAuxInfo::GetRecvInfo() const { |
| 196 | return recv_info; | 196 | return recv_info; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | const VAddr EffectAuxInfo::GetRecvBuffer() const { | 199 | VAddr EffectAuxInfo::GetRecvBuffer() const { |
| 200 | return recv_buffer; | 200 | return recv_buffer; |
| 201 | } | 201 | } |
| 202 | 202 | ||
diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h index 2f2da72dd..2c4ce53ef 100644 --- a/src/audio_core/effect_context.h +++ b/src/audio_core/effect_context.h | |||
| @@ -166,13 +166,13 @@ public: | |||
| 166 | std::array<u8, 0xa0> raw; | 166 | std::array<u8, 0xa0> raw; |
| 167 | }; | 167 | }; |
| 168 | }; | 168 | }; |
| 169 | static_assert(sizeof(EffectInfo::InParams) == 0xc0, "InParams is an invalid size"); | 169 | static_assert(sizeof(InParams) == 0xc0, "InParams is an invalid size"); |
| 170 | 170 | ||
| 171 | struct OutParams { | 171 | struct OutParams { |
| 172 | UsageStatus status{}; | 172 | UsageStatus status{}; |
| 173 | INSERT_PADDING_BYTES(15); | 173 | INSERT_PADDING_BYTES(15); |
| 174 | }; | 174 | }; |
| 175 | static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size"); | 175 | static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size"); |
| 176 | }; | 176 | }; |
| 177 | 177 | ||
| 178 | struct AuxAddress { | 178 | struct AuxAddress { |
| @@ -184,8 +184,8 @@ struct AuxAddress { | |||
| 184 | 184 | ||
| 185 | class EffectBase { | 185 | class EffectBase { |
| 186 | public: | 186 | public: |
| 187 | EffectBase(EffectType effect_type); | 187 | explicit EffectBase(EffectType effect_type); |
| 188 | ~EffectBase(); | 188 | virtual ~EffectBase(); |
| 189 | 189 | ||
| 190 | virtual void Update(EffectInfo::InParams& in_params) = 0; | 190 | virtual void Update(EffectInfo::InParams& in_params) = 0; |
| 191 | virtual void UpdateForCommandGeneration() = 0; | 191 | virtual void UpdateForCommandGeneration() = 0; |
| @@ -206,8 +206,7 @@ protected: | |||
| 206 | template <typename T> | 206 | template <typename T> |
| 207 | class EffectGeneric : public EffectBase { | 207 | class EffectGeneric : public EffectBase { |
| 208 | public: | 208 | public: |
| 209 | EffectGeneric(EffectType effect_type) : EffectBase::EffectBase(effect_type) {} | 209 | explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {} |
| 210 | ~EffectGeneric() = default; | ||
| 211 | 210 | ||
| 212 | T& GetParams() { | 211 | T& GetParams() { |
| 213 | return internal_params; | 212 | return internal_params; |
| @@ -224,7 +223,7 @@ private: | |||
| 224 | class EffectStubbed : public EffectBase { | 223 | class EffectStubbed : public EffectBase { |
| 225 | public: | 224 | public: |
| 226 | explicit EffectStubbed(); | 225 | explicit EffectStubbed(); |
| 227 | ~EffectStubbed(); | 226 | ~EffectStubbed() override; |
| 228 | 227 | ||
| 229 | void Update(EffectInfo::InParams& in_params) override; | 228 | void Update(EffectInfo::InParams& in_params) override; |
| 230 | void UpdateForCommandGeneration() override; | 229 | void UpdateForCommandGeneration() override; |
| @@ -233,7 +232,7 @@ public: | |||
| 233 | class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> { | 232 | class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> { |
| 234 | public: | 233 | public: |
| 235 | explicit EffectI3dl2Reverb(); | 234 | explicit EffectI3dl2Reverb(); |
| 236 | ~EffectI3dl2Reverb(); | 235 | ~EffectI3dl2Reverb() override; |
| 237 | 236 | ||
| 238 | void Update(EffectInfo::InParams& in_params) override; | 237 | void Update(EffectInfo::InParams& in_params) override; |
| 239 | void UpdateForCommandGeneration() override; | 238 | void UpdateForCommandGeneration() override; |
| @@ -245,7 +244,7 @@ private: | |||
| 245 | class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> { | 244 | class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> { |
| 246 | public: | 245 | public: |
| 247 | explicit EffectBiquadFilter(); | 246 | explicit EffectBiquadFilter(); |
| 248 | ~EffectBiquadFilter(); | 247 | ~EffectBiquadFilter() override; |
| 249 | 248 | ||
| 250 | void Update(EffectInfo::InParams& in_params) override; | 249 | void Update(EffectInfo::InParams& in_params) override; |
| 251 | void UpdateForCommandGeneration() override; | 250 | void UpdateForCommandGeneration() override; |
| @@ -254,14 +253,14 @@ public: | |||
| 254 | class EffectAuxInfo : public EffectGeneric<AuxInfo> { | 253 | class EffectAuxInfo : public EffectGeneric<AuxInfo> { |
| 255 | public: | 254 | public: |
| 256 | explicit EffectAuxInfo(); | 255 | explicit EffectAuxInfo(); |
| 257 | ~EffectAuxInfo(); | 256 | ~EffectAuxInfo() override; |
| 258 | 257 | ||
| 259 | void Update(EffectInfo::InParams& in_params) override; | 258 | void Update(EffectInfo::InParams& in_params) override; |
| 260 | void UpdateForCommandGeneration() override; | 259 | void UpdateForCommandGeneration() override; |
| 261 | const VAddr GetSendInfo() const; | 260 | VAddr GetSendInfo() const; |
| 262 | const VAddr GetSendBuffer() const; | 261 | VAddr GetSendBuffer() const; |
| 263 | const VAddr GetRecvInfo() const; | 262 | VAddr GetRecvInfo() const; |
| 264 | const VAddr GetRecvBuffer() const; | 263 | VAddr GetRecvBuffer() const; |
| 265 | 264 | ||
| 266 | private: | 265 | private: |
| 267 | VAddr send_info{}; | 266 | VAddr send_info{}; |
| @@ -275,7 +274,7 @@ private: | |||
| 275 | class EffectDelay : public EffectGeneric<DelayParams> { | 274 | class EffectDelay : public EffectGeneric<DelayParams> { |
| 276 | public: | 275 | public: |
| 277 | explicit EffectDelay(); | 276 | explicit EffectDelay(); |
| 278 | ~EffectDelay(); | 277 | ~EffectDelay() override; |
| 279 | 278 | ||
| 280 | void Update(EffectInfo::InParams& in_params) override; | 279 | void Update(EffectInfo::InParams& in_params) override; |
| 281 | void UpdateForCommandGeneration() override; | 280 | void UpdateForCommandGeneration() override; |
| @@ -287,7 +286,7 @@ private: | |||
| 287 | class EffectBufferMixer : public EffectGeneric<BufferMixerParams> { | 286 | class EffectBufferMixer : public EffectGeneric<BufferMixerParams> { |
| 288 | public: | 287 | public: |
| 289 | explicit EffectBufferMixer(); | 288 | explicit EffectBufferMixer(); |
| 290 | ~EffectBufferMixer(); | 289 | ~EffectBufferMixer() override; |
| 291 | 290 | ||
| 292 | void Update(EffectInfo::InParams& in_params) override; | 291 | void Update(EffectInfo::InParams& in_params) override; |
| 293 | void UpdateForCommandGeneration() override; | 292 | void UpdateForCommandGeneration() override; |
| @@ -296,7 +295,7 @@ public: | |||
| 296 | class EffectReverb : public EffectGeneric<ReverbParams> { | 295 | class EffectReverb : public EffectGeneric<ReverbParams> { |
| 297 | public: | 296 | public: |
| 298 | explicit EffectReverb(); | 297 | explicit EffectReverb(); |
| 299 | ~EffectReverb(); | 298 | ~EffectReverb() override; |
| 300 | 299 | ||
| 301 | void Update(EffectInfo::InParams& in_params) override; | 300 | void Update(EffectInfo::InParams& in_params) override; |
| 302 | void UpdateForCommandGeneration() override; | 301 | void UpdateForCommandGeneration() override; |
diff --git a/src/audio_core/info_updater.cpp b/src/audio_core/info_updater.cpp index f53ce21a5..2940e53a9 100644 --- a/src/audio_core/info_updater.cpp +++ b/src/audio_core/info_updater.cpp | |||
| @@ -64,7 +64,6 @@ bool InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& in_behavior_info) { | |||
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | bool InfoUpdater::UpdateMemoryPools(std::vector<ServerMemoryPoolInfo>& memory_pool_info) { | 66 | bool InfoUpdater::UpdateMemoryPools(std::vector<ServerMemoryPoolInfo>& memory_pool_info) { |
| 67 | const auto force_mapping = behavior_info.IsMemoryPoolForceMappingEnabled(); | ||
| 68 | const auto memory_pool_count = memory_pool_info.size(); | 67 | const auto memory_pool_count = memory_pool_info.size(); |
| 69 | const auto total_memory_pool_in = sizeof(ServerMemoryPoolInfo::InParams) * memory_pool_count; | 68 | const auto total_memory_pool_in = sizeof(ServerMemoryPoolInfo::InParams) * memory_pool_count; |
| 70 | const auto total_memory_pool_out = sizeof(ServerMemoryPoolInfo::OutParams) * memory_pool_count; | 69 | const auto total_memory_pool_out = sizeof(ServerMemoryPoolInfo::OutParams) * memory_pool_count; |
| @@ -174,7 +173,7 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, | |||
| 174 | } | 173 | } |
| 175 | // Voice states for each channel | 174 | // Voice states for each channel |
| 176 | std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{}; | 175 | std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{}; |
| 177 | ASSERT(in_params.id < voice_count); | 176 | ASSERT(static_cast<std::size_t>(in_params.id) < voice_count); |
| 178 | 177 | ||
| 179 | // Grab our current voice info | 178 | // Grab our current voice info |
| 180 | auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id)); | 179 | auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id)); |
| @@ -352,8 +351,8 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf | |||
| 352 | for (std::size_t i = 0; i < mix_count; i++) { | 351 | for (std::size_t i = 0; i < mix_count; i++) { |
| 353 | const auto& in = mix_in_params[i]; | 352 | const auto& in = mix_in_params[i]; |
| 354 | total_buffer_count += in.buffer_count; | 353 | total_buffer_count += in.buffer_count; |
| 355 | if (in.dest_mix_id > mix_count && in.dest_mix_id != AudioCommon::NO_MIX && | 354 | if (static_cast<std::size_t>(in.dest_mix_id) > mix_count && |
| 356 | in.mix_id != AudioCommon::FINAL_MIX) { | 355 | in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) { |
| 357 | LOG_ERROR( | 356 | LOG_ERROR( |
| 358 | Audio, | 357 | Audio, |
| 359 | "Invalid mix destination, mix_id={:X}, dest_mix_id={:X}, mix_buffer_count={:X}", | 358 | "Invalid mix destination, mix_id={:X}, dest_mix_id={:X}, mix_buffer_count={:X}", |
diff --git a/src/audio_core/mix_context.cpp b/src/audio_core/mix_context.cpp index 042891490..4bca72eb0 100644 --- a/src/audio_core/mix_context.cpp +++ b/src/audio_core/mix_context.cpp | |||
| @@ -53,7 +53,7 @@ void MixContext::UpdateDistancesFromFinalMix() { | |||
| 53 | auto mix_id = in_params.mix_id; | 53 | auto mix_id = in_params.mix_id; |
| 54 | // Needs to be referenced out of scope | 54 | // Needs to be referenced out of scope |
| 55 | s32 distance_to_final_mix{AudioCommon::FINAL_MIX}; | 55 | s32 distance_to_final_mix{AudioCommon::FINAL_MIX}; |
| 56 | for (; distance_to_final_mix < info_count; distance_to_final_mix++) { | 56 | for (; distance_to_final_mix < static_cast<s32>(info_count); distance_to_final_mix++) { |
| 57 | if (mix_id == AudioCommon::FINAL_MIX) { | 57 | if (mix_id == AudioCommon::FINAL_MIX) { |
| 58 | // If we're at the final mix, we're done | 58 | // If we're at the final mix, we're done |
| 59 | break; | 59 | break; |
| @@ -77,7 +77,7 @@ void MixContext::UpdateDistancesFromFinalMix() { | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | // If we're out of range for our distance, mark it as no final mix | 79 | // If we're out of range for our distance, mark it as no final mix |
| 80 | if (distance_to_final_mix >= info_count) { | 80 | if (distance_to_final_mix >= static_cast<s32>(info_count)) { |
| 81 | distance_to_final_mix = AudioCommon::NO_FINAL_MIX; | 81 | distance_to_final_mix = AudioCommon::NO_FINAL_MIX; |
| 82 | } | 82 | } |
| 83 | 83 | ||
diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp index 79bb2f516..f21b53147 100644 --- a/src/audio_core/splitter_context.cpp +++ b/src/audio_core/splitter_context.cpp | |||
| @@ -306,7 +306,7 @@ bool SplitterContext::UpdateInfo(const std::vector<u8>& input, std::size_t& inpu | |||
| 306 | break; | 306 | break; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | if (header.send_id < 0 || header.send_id > info_count) { | 309 | if (header.send_id < 0 || static_cast<std::size_t>(header.send_id) > info_count) { |
| 310 | LOG_ERROR(Audio, "Bad splitter data id"); | 310 | LOG_ERROR(Audio, "Bad splitter data id"); |
| 311 | break; | 311 | break; |
| 312 | } | 312 | } |
| @@ -348,7 +348,7 @@ bool SplitterContext::UpdateData(const std::vector<u8>& input, std::size_t& inpu | |||
| 348 | break; | 348 | break; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | if (header.splitter_id < 0 || header.splitter_id > data_count) { | 351 | if (header.splitter_id < 0 || static_cast<std::size_t>(header.splitter_id) > data_count) { |
| 352 | LOG_ERROR(Audio, "Bad splitter data id"); | 352 | LOG_ERROR(Audio, "Bad splitter data id"); |
| 353 | break; | 353 | break; |
| 354 | } | 354 | } |
| @@ -434,7 +434,7 @@ const std::vector<s32>& NodeStates::GetIndexList() const { | |||
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | void NodeStates::PushTsortResult(s32 index) { | 436 | void NodeStates::PushTsortResult(s32 index) { |
| 437 | ASSERT(index < node_count); | 437 | ASSERT(index < static_cast<s32>(node_count)); |
| 438 | index_list[index_pos++] = index; | 438 | index_list[index_pos++] = index; |
| 439 | } | 439 | } |
| 440 | 440 | ||
diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp index 1d8f69844..863ac9267 100644 --- a/src/audio_core/voice_context.cpp +++ b/src/audio_core/voice_context.cpp | |||
| @@ -488,11 +488,11 @@ s32 VoiceContext::DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer, | |||
| 488 | 488 | ||
| 489 | // Fast path | 489 | // Fast path |
| 490 | if (channel_count == 1) { | 490 | if (channel_count == 1) { |
| 491 | for (std::size_t i = 0; i < samples_processed; i++) { | 491 | for (std::ptrdiff_t i = 0; i < samples_processed; i++) { |
| 492 | output_buffer[i] = buffer_data[i]; | 492 | output_buffer[i] = buffer_data[i]; |
| 493 | } | 493 | } |
| 494 | } else { | 494 | } else { |
| 495 | for (std::size_t i = 0; i < samples_processed; i++) { | 495 | for (std::ptrdiff_t i = 0; i < samples_processed; i++) { |
| 496 | output_buffer[i] = buffer_data[i * channel_count + channel]; | 496 | output_buffer[i] = buffer_data[i * channel_count + channel]; |
| 497 | } | 497 | } |
| 498 | } | 498 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index bdae8b887..fcb612864 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -22,6 +22,18 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std:: | |||
| 22 | switch (static_cast<IoctlCommand>(command.raw)) { | 22 | switch (static_cast<IoctlCommand>(command.raw)) { |
| 23 | case IoctlCommand::IocSetNVMAPfdCommand: | 23 | case IoctlCommand::IocSetNVMAPfdCommand: |
| 24 | return SetNVMAPfd(input, output); | 24 | return SetNVMAPfd(input, output); |
| 25 | case IoctlCommand::IocSubmit: | ||
| 26 | return Submit(input, output); | ||
| 27 | case IoctlCommand::IocGetSyncpoint: | ||
| 28 | return GetSyncpoint(input, output); | ||
| 29 | case IoctlCommand::IocGetWaitbase: | ||
| 30 | return GetWaitbase(input, output); | ||
| 31 | case IoctlCommand::IocMapBuffer: | ||
| 32 | return MapBuffer(input, output); | ||
| 33 | case IoctlCommand::IocMapBufferEx: | ||
| 34 | return MapBufferEx(input, output); | ||
| 35 | case IoctlCommand::IocUnmapBufferEx: | ||
| 36 | return UnmapBufferEx(input, output); | ||
| 25 | } | 37 | } |
| 26 | 38 | ||
| 27 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); | 39 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| @@ -30,11 +42,67 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, const std:: | |||
| 30 | 42 | ||
| 31 | u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { | 43 | u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { |
| 32 | IoctlSetNvmapFD params{}; | 44 | IoctlSetNvmapFD params{}; |
| 33 | std::memcpy(¶ms, input.data(), input.size()); | 45 | std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD)); |
| 34 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); | 46 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
| 35 | 47 | ||
| 36 | nvmap_fd = params.nvmap_fd; | 48 | nvmap_fd = params.nvmap_fd; |
| 37 | return 0; | 49 | return 0; |
| 38 | } | 50 | } |
| 39 | 51 | ||
| 52 | u32 nvhost_nvdec::Submit(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 53 | IoctlSubmit params{}; | ||
| 54 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); | ||
| 55 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 56 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | u32 nvhost_nvdec::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 61 | IoctlGetSyncpoint params{}; | ||
| 62 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); | ||
| 63 | LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); | ||
| 64 | params.value = 0; // Seems to be hard coded at 0 | ||
| 65 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | u32 nvhost_nvdec::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 70 | IoctlGetWaitbase params{}; | ||
| 71 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); | ||
| 72 | LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); | ||
| 73 | params.value = 0; // Seems to be hard coded at 0 | ||
| 74 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase)); | ||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | u32 nvhost_nvdec::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 79 | IoctlMapBuffer params{}; | ||
| 80 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); | ||
| 81 | LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, | ||
| 82 | params.address_1); | ||
| 83 | params.address_1 = 0; | ||
| 84 | params.address_2 = 0; | ||
| 85 | std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | u32 nvhost_nvdec::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 90 | IoctlMapBufferEx params{}; | ||
| 91 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx)); | ||
| 92 | LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, | ||
| 93 | params.address_1); | ||
| 94 | params.address_1 = 0; | ||
| 95 | params.address_2 = 0; | ||
| 96 | std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx)); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | u32 nvhost_nvdec::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 101 | IoctlUnmapBufferEx params{}; | ||
| 102 | std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); | ||
| 103 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 104 | std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx)); | ||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 40 | } // namespace Service::Nvidia::Devices | 108 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index cbdac8069..4332db118 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | |||
| @@ -23,16 +23,66 @@ public: | |||
| 23 | private: | 23 | private: |
| 24 | enum class IoctlCommand : u32_le { | 24 | enum class IoctlCommand : u32_le { |
| 25 | IocSetNVMAPfdCommand = 0x40044801, | 25 | IocSetNVMAPfdCommand = 0x40044801, |
| 26 | IocSubmit = 0xC0400001, | ||
| 27 | IocGetSyncpoint = 0xC0080002, | ||
| 28 | IocGetWaitbase = 0xC0080003, | ||
| 29 | IocMapBuffer = 0xC01C0009, | ||
| 30 | IocMapBufferEx = 0xC0A40009, | ||
| 31 | IocUnmapBufferEx = 0xC0A4000A, | ||
| 26 | }; | 32 | }; |
| 27 | 33 | ||
| 28 | struct IoctlSetNvmapFD { | 34 | struct IoctlSetNvmapFD { |
| 29 | u32_le nvmap_fd; | 35 | u32_le nvmap_fd; |
| 30 | }; | 36 | }; |
| 31 | static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); | 37 | static_assert(sizeof(IoctlSetNvmapFD) == 0x4, "IoctlSetNvmapFD is incorrect size"); |
| 38 | |||
| 39 | struct IoctlSubmit { | ||
| 40 | INSERT_PADDING_BYTES(0x40); // TODO(DarkLordZach): RE this structure | ||
| 41 | }; | ||
| 42 | static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit has incorrect size"); | ||
| 43 | |||
| 44 | struct IoctlGetSyncpoint { | ||
| 45 | u32 unknown; // seems to be ignored? Nintendo added this | ||
| 46 | u32 value; | ||
| 47 | }; | ||
| 48 | static_assert(sizeof(IoctlGetSyncpoint) == 0x08, "IoctlGetSyncpoint has incorrect size"); | ||
| 49 | |||
| 50 | struct IoctlGetWaitbase { | ||
| 51 | u32 unknown; // seems to be ignored? Nintendo added this | ||
| 52 | u32 value; | ||
| 53 | }; | ||
| 54 | static_assert(sizeof(IoctlGetWaitbase) == 0x08, "IoctlGetWaitbase has incorrect size"); | ||
| 55 | |||
| 56 | struct IoctlMapBuffer { | ||
| 57 | u32 unknown; | ||
| 58 | u32 address_1; | ||
| 59 | u32 address_2; | ||
| 60 | INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure | ||
| 61 | }; | ||
| 62 | static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size"); | ||
| 63 | |||
| 64 | struct IoctlMapBufferEx { | ||
| 65 | u32 unknown; | ||
| 66 | u32 address_1; | ||
| 67 | u32 address_2; | ||
| 68 | INSERT_PADDING_BYTES(0x98); // TODO(DarkLordZach): RE this structure | ||
| 69 | }; | ||
| 70 | static_assert(sizeof(IoctlMapBufferEx) == 0xA4, "IoctlMapBufferEx has incorrect size"); | ||
| 71 | |||
| 72 | struct IoctlUnmapBufferEx { | ||
| 73 | INSERT_PADDING_BYTES(0xA4); // TODO(DarkLordZach): RE this structure | ||
| 74 | }; | ||
| 75 | static_assert(sizeof(IoctlUnmapBufferEx) == 0xA4, "IoctlUnmapBufferEx has incorrect size"); | ||
| 32 | 76 | ||
| 33 | u32_le nvmap_fd{}; | 77 | u32_le nvmap_fd{}; |
| 34 | 78 | ||
| 35 | u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); | 79 | u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); |
| 80 | u32 Submit(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 81 | u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 82 | u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 83 | u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 84 | u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 85 | u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 36 | }; | 86 | }; |
| 37 | 87 | ||
| 38 | } // namespace Service::Nvidia::Devices | 88 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index c695b8863..9da19ad56 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp | |||
| @@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve | |||
| 22 | switch (static_cast<IoctlCommand>(command.raw)) { | 22 | switch (static_cast<IoctlCommand>(command.raw)) { |
| 23 | case IoctlCommand::IocSetNVMAPfdCommand: | 23 | case IoctlCommand::IocSetNVMAPfdCommand: |
| 24 | return SetNVMAPfd(input, output); | 24 | return SetNVMAPfd(input, output); |
| 25 | case IoctlCommand::IocSubmit: | ||
| 26 | return Submit(input, output); | ||
| 27 | case IoctlCommand::IocGetSyncpoint: | ||
| 28 | return GetSyncpoint(input, output); | ||
| 29 | case IoctlCommand::IocGetWaitbase: | ||
| 30 | return GetWaitbase(input, output); | ||
| 31 | case IoctlCommand::IocMapBuffer: | ||
| 32 | return MapBuffer(input, output); | ||
| 33 | case IoctlCommand::IocMapBufferEx: | ||
| 34 | return MapBuffer(input, output); | ||
| 35 | case IoctlCommand::IocUnmapBufferEx: | ||
| 36 | return UnmapBufferEx(input, output); | ||
| 25 | } | 37 | } |
| 26 | 38 | ||
| 27 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); | 39 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| @@ -30,11 +42,71 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve | |||
| 30 | 42 | ||
| 31 | u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { | 43 | u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) { |
| 32 | IoctlSetNvmapFD params{}; | 44 | IoctlSetNvmapFD params{}; |
| 33 | std::memcpy(¶ms, input.data(), input.size()); | 45 | std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD)); |
| 34 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); | 46 | LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); |
| 35 | 47 | ||
| 36 | nvmap_fd = params.nvmap_fd; | 48 | nvmap_fd = params.nvmap_fd; |
| 37 | return 0; | 49 | return 0; |
| 38 | } | 50 | } |
| 39 | 51 | ||
| 52 | u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 53 | IoctlSubmit params{}; | ||
| 54 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit)); | ||
| 55 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 56 | |||
| 57 | // Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU | ||
| 58 | params.command_buffer = {}; | ||
| 59 | |||
| 60 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 65 | IoctlGetSyncpoint params{}; | ||
| 66 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); | ||
| 67 | LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); | ||
| 68 | params.value = 0; // Seems to be hard coded at 0 | ||
| 69 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint)); | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 74 | IoctlGetWaitbase params{}; | ||
| 75 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase)); | ||
| 76 | LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown); | ||
| 77 | params.value = 0; // Seems to be hard coded at 0 | ||
| 78 | std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase)); | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 83 | IoctlMapBuffer params{}; | ||
| 84 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer)); | ||
| 85 | LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, | ||
| 86 | params.address_1); | ||
| 87 | params.address_1 = 0; | ||
| 88 | params.address_2 = 0; | ||
| 89 | std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer)); | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 94 | IoctlMapBufferEx params{}; | ||
| 95 | std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx)); | ||
| 96 | LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2, | ||
| 97 | params.address_1); | ||
| 98 | params.address_1 = 0; | ||
| 99 | params.address_2 = 0; | ||
| 100 | std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx)); | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 105 | IoctlUnmapBufferEx params{}; | ||
| 106 | std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx)); | ||
| 107 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | ||
| 108 | std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx)); | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 40 | } // namespace Service::Nvidia::Devices | 112 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h index bec32bea1..a7bb7bbd5 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <vector> | 8 | #include <vector> |
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| @@ -23,6 +24,12 @@ public: | |||
| 23 | private: | 24 | private: |
| 24 | enum class IoctlCommand : u32_le { | 25 | enum class IoctlCommand : u32_le { |
| 25 | IocSetNVMAPfdCommand = 0x40044801, | 26 | IocSetNVMAPfdCommand = 0x40044801, |
| 27 | IocSubmit = 0xC0400001, | ||
| 28 | IocGetSyncpoint = 0xC0080002, | ||
| 29 | IocGetWaitbase = 0xC0080003, | ||
| 30 | IocMapBuffer = 0xC01C0009, | ||
| 31 | IocMapBufferEx = 0xC03C0009, | ||
| 32 | IocUnmapBufferEx = 0xC03C000A, | ||
| 26 | }; | 33 | }; |
| 27 | 34 | ||
| 28 | struct IoctlSetNvmapFD { | 35 | struct IoctlSetNvmapFD { |
| @@ -30,9 +37,65 @@ private: | |||
| 30 | }; | 37 | }; |
| 31 | static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); | 38 | static_assert(sizeof(IoctlSetNvmapFD) == 4, "IoctlSetNvmapFD is incorrect size"); |
| 32 | 39 | ||
| 40 | struct IoctlSubmitCommandBuffer { | ||
| 41 | u32 id; | ||
| 42 | u32 offset; | ||
| 43 | u32 count; | ||
| 44 | }; | ||
| 45 | static_assert(sizeof(IoctlSubmitCommandBuffer) == 0xC, | ||
| 46 | "IoctlSubmitCommandBuffer is incorrect size"); | ||
| 47 | |||
| 48 | struct IoctlSubmit { | ||
| 49 | u32 command_buffer_count; | ||
| 50 | u32 relocations_count; | ||
| 51 | u32 syncpt_count; | ||
| 52 | u32 wait_count; | ||
| 53 | std::array<IoctlSubmitCommandBuffer, 4> command_buffer; | ||
| 54 | }; | ||
| 55 | static_assert(sizeof(IoctlSubmit) == 0x40, "IoctlSubmit is incorrect size"); | ||
| 56 | |||
| 57 | struct IoctlGetSyncpoint { | ||
| 58 | u32 unknown; // seems to be ignored? Nintendo added this | ||
| 59 | u32 value; | ||
| 60 | }; | ||
| 61 | static_assert(sizeof(IoctlGetSyncpoint) == 0x8, "IoctlGetSyncpoint is incorrect size"); | ||
| 62 | |||
| 63 | struct IoctlGetWaitbase { | ||
| 64 | u32 unknown; // seems to be ignored? Nintendo added this | ||
| 65 | u32 value; | ||
| 66 | }; | ||
| 67 | static_assert(sizeof(IoctlGetWaitbase) == 0x8, "IoctlGetWaitbase is incorrect size"); | ||
| 68 | |||
| 69 | struct IoctlMapBuffer { | ||
| 70 | u32 unknown; | ||
| 71 | u32 address_1; | ||
| 72 | u32 address_2; | ||
| 73 | INSERT_PADDING_BYTES(0x10); // TODO(DarkLordZach): RE this structure | ||
| 74 | }; | ||
| 75 | static_assert(sizeof(IoctlMapBuffer) == 0x1C, "IoctlMapBuffer is incorrect size"); | ||
| 76 | |||
| 77 | struct IoctlMapBufferEx { | ||
| 78 | u32 unknown; | ||
| 79 | u32 address_1; | ||
| 80 | u32 address_2; | ||
| 81 | INSERT_PADDING_BYTES(0x30); // TODO(DarkLordZach): RE this structure | ||
| 82 | }; | ||
| 83 | static_assert(sizeof(IoctlMapBufferEx) == 0x3C, "IoctlMapBufferEx is incorrect size"); | ||
| 84 | |||
| 85 | struct IoctlUnmapBufferEx { | ||
| 86 | INSERT_PADDING_BYTES(0x3C); // TODO(DarkLordZach): RE this structure | ||
| 87 | }; | ||
| 88 | static_assert(sizeof(IoctlUnmapBufferEx) == 0x3C, "IoctlUnmapBufferEx is incorrect size"); | ||
| 89 | |||
| 33 | u32_le nvmap_fd{}; | 90 | u32_le nvmap_fd{}; |
| 34 | 91 | ||
| 35 | u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); | 92 | u32 SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output); |
| 93 | u32 Submit(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 94 | u32 GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 95 | u32 GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 96 | u32 MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 97 | u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 98 | u32 UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 36 | }; | 99 | }; |
| 37 | 100 | ||
| 38 | } // namespace Service::Nvidia::Devices | 101 | } // namespace Service::Nvidia::Devices |
diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp index 5218c875b..1b59612b9 100644 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp +++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp | |||
| @@ -120,7 +120,8 @@ void VKStreamBuffer::CreateBuffers(VkBufferUsageFlags usage) { | |||
| 120 | 120 | ||
| 121 | // Substract from the preferred heap size some bytes to avoid getting out of memory. | 121 | // Substract from the preferred heap size some bytes to avoid getting out of memory. |
| 122 | const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size; | 122 | const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size; |
| 123 | const VkDeviceSize allocable_size = heap_size - 9 * 1024 * 1024; | 123 | // As per DXVK's example, using `heap_size / 2` |
| 124 | const VkDeviceSize allocable_size = heap_size / 2; | ||
| 124 | buffer = device.GetLogical().CreateBuffer({ | 125 | buffer = device.GetLogical().CreateBuffer({ |
| 125 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, | 126 | .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, |
| 126 | .pNext = nullptr, | 127 | .pNext = nullptr, |
diff --git a/src/video_core/shader/registry.cpp b/src/video_core/shader/registry.cpp index cdf274e54..148d91fcb 100644 --- a/src/video_core/shader/registry.cpp +++ b/src/video_core/shader/registry.cpp | |||
| @@ -24,44 +24,45 @@ GraphicsInfo MakeGraphicsInfo(ShaderType shader_stage, ConstBufferEngineInterfac | |||
| 24 | if (shader_stage == ShaderType::Compute) { | 24 | if (shader_stage == ShaderType::Compute) { |
| 25 | return {}; | 25 | return {}; |
| 26 | } | 26 | } |
| 27 | auto& graphics = static_cast<Tegra::Engines::Maxwell3D&>(engine); | 27 | |
| 28 | 28 | auto& graphics = dynamic_cast<Tegra::Engines::Maxwell3D&>(engine); | |
| 29 | GraphicsInfo info; | 29 | |
| 30 | info.tfb_layouts = graphics.regs.tfb_layouts; | 30 | return { |
| 31 | info.tfb_varying_locs = graphics.regs.tfb_varying_locs; | 31 | .tfb_layouts = graphics.regs.tfb_layouts, |
| 32 | info.primitive_topology = graphics.regs.draw.topology; | 32 | .tfb_varying_locs = graphics.regs.tfb_varying_locs, |
| 33 | info.tessellation_primitive = graphics.regs.tess_mode.prim; | 33 | .primitive_topology = graphics.regs.draw.topology, |
| 34 | info.tessellation_spacing = graphics.regs.tess_mode.spacing; | 34 | .tessellation_primitive = graphics.regs.tess_mode.prim, |
| 35 | info.tfb_enabled = graphics.regs.tfb_enabled; | 35 | .tessellation_spacing = graphics.regs.tess_mode.spacing, |
| 36 | info.tessellation_clockwise = graphics.regs.tess_mode.cw; | 36 | .tfb_enabled = graphics.regs.tfb_enabled != 0, |
| 37 | return info; | 37 | .tessellation_clockwise = graphics.regs.tess_mode.cw.Value() != 0, |
| 38 | }; | ||
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | ComputeInfo MakeComputeInfo(ShaderType shader_stage, ConstBufferEngineInterface& engine) { | 41 | ComputeInfo MakeComputeInfo(ShaderType shader_stage, ConstBufferEngineInterface& engine) { |
| 41 | if (shader_stage != ShaderType::Compute) { | 42 | if (shader_stage != ShaderType::Compute) { |
| 42 | return {}; | 43 | return {}; |
| 43 | } | 44 | } |
| 44 | auto& compute = static_cast<Tegra::Engines::KeplerCompute&>(engine); | 45 | |
| 46 | auto& compute = dynamic_cast<Tegra::Engines::KeplerCompute&>(engine); | ||
| 45 | const auto& launch = compute.launch_description; | 47 | const auto& launch = compute.launch_description; |
| 46 | 48 | ||
| 47 | ComputeInfo info; | 49 | return { |
| 48 | info.workgroup_size = {launch.block_dim_x, launch.block_dim_y, launch.block_dim_z}; | 50 | .workgroup_size = {launch.block_dim_x, launch.block_dim_y, launch.block_dim_z}, |
| 49 | info.local_memory_size_in_words = launch.local_pos_alloc; | 51 | .shared_memory_size_in_words = launch.shared_alloc, |
| 50 | info.shared_memory_size_in_words = launch.shared_alloc; | 52 | .local_memory_size_in_words = launch.local_pos_alloc, |
| 51 | return info; | 53 | }; |
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | } // Anonymous namespace | 56 | } // Anonymous namespace |
| 55 | 57 | ||
| 56 | Registry::Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info) | 58 | Registry::Registry(ShaderType shader_stage, const SerializedRegistryInfo& info) |
| 57 | : stage{shader_stage}, stored_guest_driver_profile{info.guest_driver_profile}, | 59 | : stage{shader_stage}, stored_guest_driver_profile{info.guest_driver_profile}, |
| 58 | bound_buffer{info.bound_buffer}, graphics_info{info.graphics}, compute_info{info.compute} {} | 60 | bound_buffer{info.bound_buffer}, graphics_info{info.graphics}, compute_info{info.compute} {} |
| 59 | 61 | ||
| 60 | Registry::Registry(Tegra::Engines::ShaderType shader_stage, | 62 | Registry::Registry(ShaderType shader_stage, ConstBufferEngineInterface& engine_) |
| 61 | Tegra::Engines::ConstBufferEngineInterface& engine) | 63 | : stage{shader_stage}, engine{&engine_}, bound_buffer{engine_.GetBoundBuffer()}, |
| 62 | : stage{shader_stage}, engine{&engine}, bound_buffer{engine.GetBoundBuffer()}, | 64 | graphics_info{MakeGraphicsInfo(shader_stage, engine_)}, compute_info{MakeComputeInfo( |
| 63 | graphics_info{MakeGraphicsInfo(shader_stage, engine)}, compute_info{MakeComputeInfo( | 65 | shader_stage, engine_)} {} |
| 64 | shader_stage, engine)} {} | ||
| 65 | 66 | ||
| 66 | Registry::~Registry() = default; | 67 | Registry::~Registry() = default; |
| 67 | 68 | ||
| @@ -113,8 +114,7 @@ std::optional<Tegra::Engines::SamplerDescriptor> Registry::ObtainSeparateSampler | |||
| 113 | return value; | 114 | return value; |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | std::optional<Tegra::Engines::SamplerDescriptor> Registry::ObtainBindlessSampler(u32 buffer, | 117 | std::optional<SamplerDescriptor> Registry::ObtainBindlessSampler(u32 buffer, u32 offset) { |
| 117 | u32 offset) { | ||
| 118 | const std::pair key = {buffer, offset}; | 118 | const std::pair key = {buffer, offset}; |
| 119 | const auto iter = bindless_samplers.find(key); | 119 | const auto iter = bindless_samplers.find(key); |
| 120 | if (iter != bindless_samplers.end()) { | 120 | if (iter != bindless_samplers.end()) { |
diff --git a/src/video_core/shader/registry.h b/src/video_core/shader/registry.h index 231206765..4bebefdde 100644 --- a/src/video_core/shader/registry.h +++ b/src/video_core/shader/registry.h | |||
| @@ -94,7 +94,7 @@ public: | |||
| 94 | explicit Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info); | 94 | explicit Registry(Tegra::Engines::ShaderType shader_stage, const SerializedRegistryInfo& info); |
| 95 | 95 | ||
| 96 | explicit Registry(Tegra::Engines::ShaderType shader_stage, | 96 | explicit Registry(Tegra::Engines::ShaderType shader_stage, |
| 97 | Tegra::Engines::ConstBufferEngineInterface& engine); | 97 | Tegra::Engines::ConstBufferEngineInterface& engine_); |
| 98 | 98 | ||
| 99 | ~Registry(); | 99 | ~Registry(); |
| 100 | 100 | ||