diff --git a/README.md b/README.md index c3c9e2615..b8765bfe8 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1848. +This is the source code for early-access 1850. ## Legal Notice diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1c3dde31d..65a4922ea 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,14 +45,23 @@ if (MSVC) /Zc:inline /Zc:throwingNew + # External headers diagnostics + /experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later + /external:anglebrackets # Treats all headers included by #include
, where the header file is enclosed in angle brackets (< >), as external headers + /external:W0 # Sets the default warning level to 0 for external headers, effectively turning off warnings for external headers + # Warnings /W3 - /we4062 # enumerator 'identifier' in a switch of enum 'enumeration' is not handled + /we4018 # 'expression': signed/unsigned mismatch + /we4062 # Enumerator 'identifier' in a switch of enum 'enumeration' is not handled /we4101 # 'identifier': unreferenced local variable /we4189 # 'identifier': local variable is initialized but not referenced /we4265 # 'class': class has virtual functions, but destructor is not virtual - /we4388 # signed/unsigned mismatch - /we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect + /we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data + /we4305 # 'context': truncation from 'type1' to 'type2' + /we4388 # 'expression': signed/unsigned mismatch + /we4389 # 'operator': signed/unsigned mismatch + /we4547 # 'operator': operator before comma has no effect; expected operator with side-effect /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? /we4555 # Expression has no effect; expected expression with side-effect /we4715 # 'function': not all control paths return a value diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index 27437f1ea..15ee1b319 100755 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp @@ -400,7 +400,10 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo } } else { switch (in_params.sample_format) { + case SampleFormat::Pcm8: case SampleFormat::Pcm16: + case SampleFormat::Pcm32: + case SampleFormat::PcmFloat: DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel, worker_params.sample_rate, worker_params.sample_count, in_params.node_id); @@ -1003,9 +1006,10 @@ void CommandGenerator::GenerateFinalMixCommand() { } } -s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state, - s32 sample_start_offset, s32 sample_end_offset, s32 sample_count, - s32 channel, std::size_t mix_offset) { +template +s32 CommandGenerator::DecodePcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, + s32 sample_start_offset, s32 sample_end_offset, s32 sample_count, + s32 channel, std::size_t mix_offset) { const auto& in_params = voice_info.GetInParams(); const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; if (wave_buffer.buffer_address == 0) { @@ -1019,21 +1023,20 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s } const auto samples_remaining = (sample_end_offset - sample_start_offset) - dsp_state.offset; const auto start_offset = - ((dsp_state.offset + sample_start_offset) * in_params.channel_count) * sizeof(s16); + ((dsp_state.offset + sample_start_offset) * in_params.channel_count) * sizeof(T); const auto buffer_pos = wave_buffer.buffer_address + start_offset; const auto samples_processed = std::min(sample_count, samples_remaining); - if (in_params.channel_count == 1) { - std::vector buffer(samples_processed); - memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); - for (std::size_t i = 0; i < buffer.size(); i++) { - sample_buffer[mix_offset + i] = buffer[i]; + const auto channel_count = in_params.channel_count; + std::vector buffer(samples_processed * channel_count); + memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(T)); + + if constexpr (std::is_floating_point_v) { + for (std::size_t i = 0; i < static_cast(samples_processed); i++) { + sample_buffer[mix_offset + i] = static_cast(buffer[i * channel_count + channel] * + std::numeric_limits::max()); } } else { - const auto channel_count = in_params.channel_count; - std::vector buffer(samples_processed * channel_count); - memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); - for (std::size_t i = 0; i < static_cast(samples_processed); i++) { sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; } @@ -1249,10 +1252,25 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o s32 samples_decoded{0}; switch (in_params.sample_format) { + case SampleFormat::Pcm8: + samples_decoded = + DecodePcm(voice_info, dsp_state, samples_offset_start, samples_offset_end, + samples_to_read - samples_read, channel, temp_mix_offset); + break; case SampleFormat::Pcm16: samples_decoded = - DecodePcm16(voice_info, dsp_state, samples_offset_start, samples_offset_end, - samples_to_read - samples_read, channel, temp_mix_offset); + DecodePcm(voice_info, dsp_state, samples_offset_start, samples_offset_end, + samples_to_read - samples_read, channel, temp_mix_offset); + break; + case SampleFormat::Pcm32: + samples_decoded = + DecodePcm(voice_info, dsp_state, samples_offset_start, samples_offset_end, + samples_to_read - samples_read, channel, temp_mix_offset); + break; + case SampleFormat::PcmFloat: + samples_decoded = + DecodePcm(voice_info, dsp_state, samples_offset_start, samples_offset_end, + samples_to_read - samples_read, channel, temp_mix_offset); break; case SampleFormat::Adpcm: samples_decoded = diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h index 673e4fbef..f310d7317 100755 --- a/src/audio_core/command_generator.h +++ b/src/audio_core/command_generator.h @@ -86,8 +86,9 @@ private: std::vector& work_buffer); void UpdateI3dl2Reverb(I3dl2ReverbParams& info, I3dl2ReverbState& state, bool should_clear); // DSP Code - s32 DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_start_offset, - s32 sample_end_offset, s32 sample_count, s32 channel, std::size_t mix_offset); + template + s32 DecodePcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_start_offset, + s32 sample_end_offset, s32 sample_count, s32 channel, std::size_t mix_offset); s32 DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_start_offset, s32 sample_end_offset, s32 sample_count, s32 channel, std::size_t mix_offset); void DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* output, VoiceState& dsp_state, diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 80cfdf55b..c83072a3d 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -656,17 +656,14 @@ endif() if (MSVC) target_compile_options(core PRIVATE - /we4018 # 'expression' : signed/unsigned mismatch - /we4244 # 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point) - /we4245 # 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch + /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data + /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data + /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data - /we4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data - /we4305 # 'context' : truncation from 'type1' to 'type2' /we4456 # Declaration of 'identifier' hides previous local declaration /we4457 # Declaration of 'identifier' hides function parameter /we4458 # Declaration of 'identifier' hides class member /we4459 # Declaration of 'identifier' hides global declaration - /we4715 # 'function' : not all control paths return a value ) else() target_compile_options(core PRIVATE diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index 7c5763f9c..c3423c815 100755 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -34,18 +34,10 @@ if (MSVC) /W4 /WX - # 'expression' : signed/unsigned mismatch - /we4018 - # 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point) - /we4244 - # 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch - /we4245 - # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data - /we4254 - # 'var' : conversion from 'size_t' to 'type', possible loss of data - /we4267 - # 'context' : truncation from 'type1' to 'type2' - /we4305 + /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data + /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data + /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch + /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data ) else() target_compile_options(input_common PRIVATE diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp index 4b8de2bfe..3c3b6fbde 100755 --- a/src/input_common/gcadapter/gc_adapter.cpp +++ b/src/input_common/gcadapter/gc_adapter.cpp @@ -5,14 +5,7 @@ #include #include -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4200) // nonstandard extension used : zero-sized array in struct/union -#endif #include -#ifdef _MSC_VER -#pragma warning(pop) -#endif #include "common/logging/log.h" #include "common/param_package.h" diff --git a/src/input_common/udp/protocol.h b/src/input_common/udp/protocol.h index a3d276697..1bdc9209e 100755 --- a/src/input_common/udp/protocol.h +++ b/src/input_common/udp/protocol.h @@ -8,14 +8,7 @@ #include #include -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4701) -#endif #include -#ifdef _MSC_VER -#pragma warning(pop) -#endif #include "common/bit_field.h" #include "common/swap.h" diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index e31eb30c0..e4de55f4d 100755 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -292,13 +292,12 @@ endif() if (MSVC) target_compile_options(video_core PRIVATE - /we4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data - /we4244 # 'var' : conversion from integer to 'type', possible loss of data + /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data + /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data /we4456 # Declaration of 'identifier' hides previous local declaration /we4457 # Declaration of 'identifier' hides function parameter /we4458 # Declaration of 'identifier' hides class member /we4459 # Declaration of 'identifier' hides global declaration - /we4715 # 'function' : not all control paths return a value ) else() target_compile_options(video_core PRIVATE diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/command_classes/codecs/codec.h index f2aef1699..96c823c76 100755 --- a/src/video_core/command_classes/codecs/codec.h +++ b/src/video_core/command_classes/codecs/codec.h @@ -14,18 +14,10 @@ extern "C" { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4242) // conversion from 'type' to 'type', possible loss of data -#pragma warning(disable : 4244) // conversion from 'type' to 'type', possible loss of data -#endif #include #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif -#ifdef _MSC_VER -#pragma warning(pop) -#endif } namespace Tegra { diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp index 5faf8c0f1..ff3db0aee 100755 --- a/src/video_core/command_classes/vic.cpp +++ b/src/video_core/command_classes/vic.cpp @@ -9,17 +9,10 @@ extern "C" { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" #endif -#ifdef _MSC_VER -#pragma warning(disable : 4244) // conversion from 'type' to 'type', possible loss of data -#pragma warning(push) -#endif #include #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif -#ifdef _MSC_VER -#pragma warning(pop) -#endif } #include "common/assert.h" diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index b95750fd3..0f640fdae 100755 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp @@ -7,10 +7,6 @@ #include "video_core/engines/fermi_2d.h" #include "video_core/memory_manager.h" #include "video_core/rasterizer_interface.h" -#include "video_core/surface.h" - -using VideoCore::Surface::BytesPerBlock; -using VideoCore::Surface::PixelFormatFromRenderTargetFormat; namespace Tegra::Engines { @@ -53,7 +49,7 @@ void Fermi2D::Blit() { UNIMPLEMENTED_IF_MSG(regs.clip_enable != 0, "Clipped blit enabled"); const auto& args = regs.pixels_from_memory; - Config config{ + const Config config{ .operation = regs.operation, .filter = args.sample_mode.filter, .dst_x0 = args.dst_x0, @@ -65,20 +61,7 @@ void Fermi2D::Blit() { .src_x1 = static_cast((args.du_dx * args.dst_width + args.src_x0) >> 32), .src_y1 = static_cast((args.dv_dy * args.dst_height + args.src_y0) >> 32), }; - Surface src = regs.src; - const auto bytes_per_pixel = BytesPerBlock(PixelFormatFromRenderTargetFormat(src.format)); - const auto need_align_to_pitch = - src.linear == Tegra::Engines::Fermi2D::MemoryLayout::Pitch && src.width == config.src_x1 && - config.src_x1 > static_cast(src.pitch / bytes_per_pixel) && config.src_x0 > 0; - if (need_align_to_pitch) { - auto address = src.Address() + config.src_x0 * bytes_per_pixel; - src.addr_upper = static_cast(address >> 32); - src.addr_lower = static_cast(address); - src.width -= config.src_x0; - config.src_x1 -= config.src_x0; - config.src_x0 = 0; - } - if (!rasterizer->AccelerateSurfaceCopy(src, regs.dst, config)) { + if (!rasterizer->AccelerateSurfaceCopy(regs.src, regs.dst, config)) { UNIMPLEMENTED(); } } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index a2c1599f7..ff0f03e99 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -327,7 +327,8 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array(internal_format)) == + ACCELERATED_FORMATS.end()) { return false; } if (format_info.compatibility_by_size) { diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp index 2aae338b6..6052d148a 100755 --- a/src/video_core/texture_cache/image_base.cpp +++ b/src/video_core/texture_cache/image_base.cpp @@ -85,7 +85,7 @@ std::optional ImageBase::TryFindBase(GPUVAddr other_addr) const if (info.type != ImageType::e3D) { const auto [layer, mip_offset] = LayerMipOffset(diff, info.layer_stride); const auto end = mip_level_offsets.begin() + info.resources.levels; - const auto it = std::find(mip_level_offsets.begin(), end, mip_offset); + const auto it = std::find(mip_level_offsets.begin(), end, static_cast(mip_offset)); if (layer > info.resources.layers || it == end) { return std::nullopt; } diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 01de2d498..e3542301e 100755 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -159,7 +159,9 @@ public: /// Blit an image with the given parameters void BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src, - const Tegra::Engines::Fermi2D::Config& copy); + const Tegra::Engines::Fermi2D::Config& copy, + std::optional src_region_override = {}, + std::optional dst_region_override = {}); /// Invalidate the contents of the color buffer index /// These contents become unspecified, the cache can assume aggressive optimizations. @@ -758,7 +760,9 @@ void TextureCache

::UnmapGPUMemory(GPUVAddr gpu_addr, size_t size) { template void TextureCache

::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src, - const Tegra::Engines::Fermi2D::Config& copy) { + const Tegra::Engines::Fermi2D::Config& copy, + std::optional src_override, + std::optional dst_override) { const BlitImages images = GetBlitImages(dst, src); const ImageId dst_id = images.dst_id; const ImageId src_id = images.src_id; @@ -769,25 +773,47 @@ void TextureCache

::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, const ImageBase& src_image = slot_images[src_id]; // TODO: Deduplicate - const std::optional src_base = src_image.TryFindBase(src.Address()); - const SubresourceRange src_range{.base = src_base.value(), .extent = {1, 1}}; - const ImageViewInfo src_view_info(ImageViewType::e2D, images.src_format, src_range); - const auto [src_framebuffer_id, src_view_id] = RenderTargetFromImage(src_id, src_view_info); - const auto [src_samples_x, src_samples_y] = SamplesLog2(src_image.info.num_samples); - const Region2D src_region{ - Offset2D{.x = copy.src_x0 >> src_samples_x, .y = copy.src_y0 >> src_samples_y}, - Offset2D{.x = copy.src_x1 >> src_samples_x, .y = copy.src_y1 >> src_samples_y}, - }; - const std::optional dst_base = dst_image.TryFindBase(dst.Address()); const SubresourceRange dst_range{.base = dst_base.value(), .extent = {1, 1}}; const ImageViewInfo dst_view_info(ImageViewType::e2D, images.dst_format, dst_range); const auto [dst_framebuffer_id, dst_view_id] = RenderTargetFromImage(dst_id, dst_view_info); - const auto [dst_samples_x, dst_samples_y] = SamplesLog2(dst_image.info.num_samples); - const Region2D dst_region{ - Offset2D{.x = copy.dst_x0 >> dst_samples_x, .y = copy.dst_y0 >> dst_samples_y}, - Offset2D{.x = copy.dst_x1 >> dst_samples_x, .y = copy.dst_y1 >> dst_samples_y}, + const auto [src_samples_x, src_samples_y] = SamplesLog2(src_image.info.num_samples); + + // out of bounds texture blit checking + const bool use_override = src_override.has_value(); + const s32 src_x0 = copy.src_x0 >> src_samples_x; + s32 src_x1 = use_override ? src_override->end.x : copy.src_x1 >> src_samples_x; + const s32 src_y0 = copy.src_y0 >> src_samples_y; + const s32 src_y1 = copy.src_y1 >> src_samples_y; + + const auto src_width = static_cast(src_image.info.size.width); + const bool width_oob = src_x1 > src_width; + const auto width_diff = width_oob ? src_x1 - src_width : 0; + if (width_oob) { + src_x1 = src_width; + } + + const Region2D src_dimensions{ + Offset2D{.x = src_x0, .y = src_y0}, + Offset2D{.x = src_x1, .y = src_y1}, }; + const auto src_region = use_override ? *src_override : src_dimensions; + + const std::optional src_base = src_image.TryFindBase(src.Address()); + const SubresourceRange src_range{.base = src_base.value(), .extent = {1, 1}}; + const ImageViewInfo src_view_info(ImageViewType::e2D, images.src_format, src_range); + const auto [src_framebuffer_id, src_view_id] = RenderTargetFromImage(src_id, src_view_info); + const auto [dst_samples_x, dst_samples_y] = SamplesLog2(dst_image.info.num_samples); + + const s32 dst_x0 = copy.dst_x0 >> dst_samples_x; + const s32 dst_x1 = copy.dst_x1 >> dst_samples_x; + const s32 dst_y0 = copy.dst_y0 >> dst_samples_y; + const s32 dst_y1 = copy.dst_y1 >> dst_samples_y; + const Region2D dst_dimensions{ + Offset2D{.x = dst_x0, .y = dst_y0}, + Offset2D{.x = dst_x1 - width_diff, .y = dst_y1}, + }; + const auto dst_region = use_override ? *dst_override : dst_dimensions; // Always call this after src_framebuffer_id was queried, as the address might be invalidated. Framebuffer* const dst_framebuffer = &slot_framebuffers[dst_framebuffer_id]; @@ -804,6 +830,21 @@ void TextureCache

::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, runtime.BlitImage(dst_framebuffer, dst_view, src_view, dst_region, src_region, copy.filter, copy.operation); } + + if (width_oob) { + // Continue copy of the oob region of the texture on the next row + auto oob_src = src; + oob_src.height++; + const Region2D src_region_override{ + Offset2D{.x = 0, .y = src_y0 + 1}, + Offset2D{.x = width_diff, .y = src_y1 + 1}, + }; + const Region2D dst_region_override{ + Offset2D{.x = dst_x1 - width_diff, .y = dst_y0}, + Offset2D{.x = dst_x1, .y = dst_y1}, + }; + BlitImage(dst, oob_src, copy, src_region_override, dst_region_override); + } } template diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index 10093a11d..c872517b8 100755 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp @@ -394,7 +394,7 @@ template const s32 mip_offset = diff % layer_stride; const std::array offsets = CalculateMipLevelOffsets(new_info); const auto end = offsets.begin() + new_info.resources.levels; - const auto it = std::find(offsets.begin(), end, mip_offset); + const auto it = std::find(offsets.begin(), end, static_cast(mip_offset)); if (it == end) { // Mipmap is not aligned to any valid size return std::nullopt; diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp index c066d8cbf..6ae035638 100755 --- a/src/video_core/textures/astc.cpp +++ b/src/video_core/textures/astc.cpp @@ -1369,8 +1369,8 @@ static void DecompressBlock(std::span inBuf, const u32 blockWidth, // each partition. // Determine partitions, partition index, and color endpoint modes - s32 planeIdx = -1; - u32 partitionIndex; + u32 planeIdx{UINT32_MAX}; + u32 partitionIndex{}; u32 colorEndpointMode[4] = {0, 0, 0, 0}; // Define color data.