diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index 018cd5bc27..b7034802ba 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -580,8 +580,8 @@ target_sources(rpcs3_emu PRIVATE RSX/RSXThread.cpp RSX/RSXZCULL.cpp RSX/rsx_methods.cpp - RSX/rsx_utils.cpp RSX/rsx_vertex_data.cpp + RSX/Utils/rsx_utils.cpp ) if(NOT ANDROID AND NOT APPLE) diff --git a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp index f57e51d2da..ce7f9fd6c9 100644 --- a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp @@ -2,7 +2,7 @@ #include "Emu/system_config.h" #include "Emu/Cell/PPUModule.h" #include "Emu/IdManager.h" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/rsx_utils.h" #include "Utilities/StrUtil.h" #include "cellMic.h" diff --git a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp index a51ffbf756..83bbb18ba8 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp @@ -3,7 +3,7 @@ #include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUModule.h" #include "Emu/IdManager.h" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/rsx_utils.h" #include "Emu/RSX/RSXThread.h" #include "cellVideoOut.h" diff --git a/rpcs3/Emu/Memory/vm_locking.h b/rpcs3/Emu/Memory/vm_locking.h index ac29a36d2d..b924300768 100644 --- a/rpcs3/Emu/Memory/vm_locking.h +++ b/rpcs3/Emu/Memory/vm_locking.h @@ -1,7 +1,7 @@ #pragma once #include "vm.h" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/rsx_utils.h" class cpu_thread; class shared_mutex; diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index 9d6e9eee9b..5e505410e8 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -2,8 +2,9 @@ #include "Emu/Memory/vm.h" #include "TextureUtils.h" #include "../RSXThread.h" -#include "../rsx_utils.h" -#include "../color_utils.h" +#include "../Utils/rsx_utils.h" +#include "../Utils/color_utils.hpp" +#include "../Utils/image_utils.hpp" #include "3rdparty/bcdec/bcdec.hpp" diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index 7d9aeea87f..3ebcf932a1 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -2,7 +2,7 @@ #include "io_buffer.h" #include "simple_array.hpp" -#include "../color_utils.h" +#include "../Utils/color_utils.hpp" #include "../RSXTexture.h" #include diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index d43875d203..817192730c 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -5,7 +5,7 @@ #include "ranged_map.hpp" #include "surface_cache_dma.hpp" #include "../gcm_enums.h" -#include "../rsx_utils.h" +#include "../Utils/rsx_utils.h" #include #include "util/asm.hpp" diff --git a/rpcs3/Emu/RSX/Common/surface_utils.h b/rpcs3/Emu/RSX/Common/surface_utils.h index a5768fa116..0db764f0b7 100644 --- a/rpcs3/Emu/RSX/Common/surface_utils.h +++ b/rpcs3/Emu/RSX/Common/surface_utils.h @@ -3,7 +3,7 @@ #include "util/types.hpp" #include "Utilities/geometry.h" #include "TextureUtils.h" -#include "../rsx_utils.h" +#include "../Utils/rsx_utils.h" #include "Emu/Memory/vm.h" #define ENABLE_SURFACE_CACHE_DEBUG 0 diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index c5dd21e76d..49983eaa23 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -3,6 +3,7 @@ #include "Emu/RSX/Common/simple_array.hpp" #include "Emu/RSX/Core/RSXContext.h" #include "Emu/RSX/RSXThread.h" +#include "Emu/RSX/Utils/algorithm.hpp" #include "texture_cache_utils.h" #include "texture_cache_predictor.h" diff --git a/rpcs3/Emu/RSX/Common/texture_cache_checker.h b/rpcs3/Emu/RSX/Common/texture_cache_checker.h index cb283cc96a..415267d9fa 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache_checker.h +++ b/rpcs3/Emu/RSX/Common/texture_cache_checker.h @@ -2,7 +2,7 @@ #ifdef TEXTURE_CACHE_DEBUG -#include "../rsx_utils.h" +#include "../Utils/rsx_utils.h" namespace rsx { diff --git a/rpcs3/Emu/RSX/Common/texture_cache_helpers.h b/rpcs3/Emu/RSX/Common/texture_cache_helpers.h index 807866eff3..e6789e84a9 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache_helpers.h +++ b/rpcs3/Emu/RSX/Common/texture_cache_helpers.h @@ -1,8 +1,8 @@ #pragma once -#include "../rsx_utils.h" #include "simple_array.hpp" #include "TextureUtils.h" +#include "../Utils/rsx_utils.h" namespace rsx { diff --git a/rpcs3/Emu/RSX/Common/texture_cache_predictor.h b/rpcs3/Emu/RSX/Common/texture_cache_predictor.h index bfa500ef1a..8ffde8eb8c 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache_predictor.h +++ b/rpcs3/Emu/RSX/Common/texture_cache_predictor.h @@ -1,7 +1,7 @@ #pragma once -#include "../rsx_utils.h" #include "TextureUtils.h" +#include "../Utils/rsx_utils.h" #include diff --git a/rpcs3/Emu/RSX/Core/RSXContext.cpp b/rpcs3/Emu/RSX/Core/RSXContext.cpp index 0ba4e880cf..43de7e1c74 100644 --- a/rpcs3/Emu/RSX/Core/RSXContext.cpp +++ b/rpcs3/Emu/RSX/Core/RSXContext.cpp @@ -1,5 +1,5 @@ #include "stdafx.h" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/algorithm.hpp" #include "RSXContext.h" namespace rsx diff --git a/rpcs3/Emu/RSX/Core/RSXContext.h b/rpcs3/Emu/RSX/Core/RSXContext.h index dd18747012..6ae9f5fc9b 100644 --- a/rpcs3/Emu/RSX/Core/RSXContext.h +++ b/rpcs3/Emu/RSX/Core/RSXContext.h @@ -3,7 +3,7 @@ #include #include "Emu/Cell/lv2/sys_rsx.h" #include "Emu/RSX/GCM.h" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/rsx_utils.h" #include "RSXIOMap.hpp" namespace rsx diff --git a/rpcs3/Emu/RSX/Core/RSXDisplay.cpp b/rpcs3/Emu/RSX/Core/RSXDisplay.cpp index f86c6dea04..e5f5371840 100644 --- a/rpcs3/Emu/RSX/Core/RSXDisplay.cpp +++ b/rpcs3/Emu/RSX/Core/RSXDisplay.cpp @@ -2,7 +2,7 @@ #include "RSXDisplay.h" #include "../Common/simple_array.hpp" -#include "../rsx_utils.h" +#include "../Utils/rsx_utils.h" namespace rsx { diff --git a/rpcs3/Emu/RSX/GL/GLCompute.h b/rpcs3/Emu/RSX/GL/GLCompute.h index 91210497c7..a086951c3b 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.h +++ b/rpcs3/Emu/RSX/GL/GLCompute.h @@ -1,9 +1,11 @@ #pragma once -#include "Emu/IdManager.h" #include "GLHelpers.h" #include "glutils/program.h" -#include "../rsx_utils.h" + +#include "Emu/IdManager.h" +#include "Emu/RSX/Utils/algorithm.hpp" +#include "Utilities/StrUtil.h" #include diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 615e2e4b6d..f9175d60d2 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -3,7 +3,7 @@ #include "GLFragmentProgram.h" #include "GLPipelineCompiler.h" #include "../Program/ProgramStateCache.h" -#include "../rsx_utils.h" +#include "../Utils/rsx_utils.h" struct GLTraits { diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index 2715aa91ec..aa37fd3319 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -1,6 +1,6 @@ #pragma once #include "../Common/surface_store.h" -#include "../rsx_utils.h" +#include "../Utils/rsx_utils.h" #include "glutils/fbo.h" diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp index 16deadd281..9dcb3cb74c 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp @@ -2,6 +2,7 @@ #include "GLTexture.h" #include "GLTextureCache.h" #include "../Common/BufferUtils.h" +#include "../Utils/image_utils.hpp" #include "util/asm.hpp" diff --git a/rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp b/rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp index 75e2d3f3db..20a755c959 100644 --- a/rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp +++ b/rpcs3/Emu/RSX/GL/upscalers/fsr1/fsr_pass.cpp @@ -26,6 +26,8 @@ #pragma clang diagnostic pop #endif +#include "Emu/system_config.h" + namespace gl { namespace FidelityFX diff --git a/rpcs3/Emu/RSX/Host/MM.cpp b/rpcs3/Emu/RSX/Host/MM.cpp index 40760c9dcc..53bd558607 100644 --- a/rpcs3/Emu/RSX/Host/MM.cpp +++ b/rpcs3/Emu/RSX/Host/MM.cpp @@ -2,6 +2,7 @@ #include "MM.h" #include #include +#include #include #include diff --git a/rpcs3/Emu/RSX/NV47/FW/draw_call.cpp b/rpcs3/Emu/RSX/NV47/FW/draw_call.cpp index d8978a78cc..feaccf72a9 100644 --- a/rpcs3/Emu/RSX/NV47/FW/draw_call.cpp +++ b/rpcs3/Emu/RSX/NV47/FW/draw_call.cpp @@ -2,7 +2,7 @@ #include "draw_call.hpp" #include "Emu/RSX/rsx_methods.h" // FIXME -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/rsx_utils.h" #include "Emu/RSX/RSXThread.h" #include "Emu/RSX/Common/BufferUtils.h" #include "Emu/RSX/NV47/HW/context.h" diff --git a/rpcs3/Emu/RSX/NV47/HW/nv3089.cpp b/rpcs3/Emu/RSX/NV47/HW/nv3089.cpp index 6ac502b462..488b66b1da 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv3089.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv3089.cpp @@ -5,6 +5,7 @@ #include "Emu/RSX/Core/RSXReservationLock.hpp" #include "Emu/RSX/Common/tiled_dma_copy.hpp" #include "Emu/RSX/Host/MM.h" +#include "Emu/RSX/Utils/image_utils.hpp" #include "context_accessors.define.h" diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp index daa2ad9fc0..5b355b1c04 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp @@ -3,7 +3,7 @@ #include "GLSLCommon.h" #include "RSXFragmentProgram.h" -#include "Emu/RSX/color_utils.h" +#include "Emu/RSX/Utils/color_utils.hpp" #include "Emu/RSX/gcm_enums.h" #include "Utilities/StrFmt.h" diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.h b/rpcs3/Emu/RSX/Program/GLSLCommon.h index b4273c4aff..dda716a4b1 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.h +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.h @@ -4,7 +4,7 @@ #include "GLSLTypes.h" #include "ShaderParam.h" -#include "../color_utils.h" +#include "../Utils/color_utils.hpp" struct RSXFragmentProgram; diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index f04968c1cf..a710d66394 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -1,9 +1,10 @@ #include "stdafx.h" #include "RSXTexture.h" -#include "rsx_utils.h" #include "Common/TextureUtils.h" #include "Program/GLSLCommon.h" +#include "Utils/algorithm.hpp" +#include "Utils/rsx_utils.h" #include "Emu/system_config.h" #include "util/simd.hpp" diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index ee635d9ce4..0de96bb8cd 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -1,6 +1,6 @@ #pragma once #include "gcm_enums.h" -#include "color_utils.h" +#include "Utils/color_utils.hpp" namespace rsx { diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 598226085b..a292e4379f 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -6,13 +6,13 @@ #include "RSXFIFO.h" #include "RSXOffload.h" #include "RSXZCULL.h" -#include "rsx_utils.h" #include "Common/bitfield.hpp" #include "Common/profiling_timer.hpp" #include "Common/texture_cache_types.h" #include "Common/TextureUtils.h" #include "Program/RSXVertexProgram.h" #include "Program/RSXFragmentProgram.h" +#include "Utils/rsx_utils.h" #include "Utilities/Thread.h" #include "Utilities/geometry.h" diff --git a/rpcs3/Emu/RSX/RSXZCULL.h b/rpcs3/Emu/RSX/RSXZCULL.h index d44cba5c95..ec6fd2ad5c 100644 --- a/rpcs3/Emu/RSX/RSXZCULL.h +++ b/rpcs3/Emu/RSX/RSXZCULL.h @@ -6,7 +6,7 @@ #include "Utilities/mutex.h" -#include "rsx_utils.h" +#include "Utils/rsx_utils.h" #include #include diff --git a/rpcs3/Emu/RSX/Utils/algorithm.hpp b/rpcs3/Emu/RSX/Utils/algorithm.hpp new file mode 100644 index 0000000000..24069f467b --- /dev/null +++ b/rpcs3/Emu/RSX/Utils/algorithm.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include +#include + +namespace rsx +{ + static constexpr u32 floor_log2(u32 value) + { + return value <= 1 ? 0 : std::countl_zero(value) ^ 31; + } + + static constexpr u32 ceil_log2(u32 value) + { + return floor_log2(value) + u32{!!(value & (value - 1))}; + } + + static constexpr u32 next_pow2(u32 x) + { + if (x <= 2) return x; + + return static_cast((1ULL << 32) >> std::countl_zero(x - 1)); + } + + static inline bool fcmp(float a, float b, float epsilon = 0.000001f) + { + return fabsf(a - b) < epsilon; + } + + // General purpose alignment without power-of-2 constraint + template + static inline T align2(T value, U alignment) + { + return ((value + alignment - 1) / alignment) * alignment; + } + + // General purpose downward alignment without power-of-2 constraint + template + static inline T align_down2(T value, U alignment) + { + return (value / alignment) * alignment; + } + + // Copy memory in inverse direction from source + // Used to scale negatively x axis while transfering image data + template + static void memcpy_r(void* dst, void* src, usz size) + { + for (u32 i = 0; i < size; i++) + { + *(static_cast(dst) + i) = *(static_cast(src) - i); + } + } +} diff --git a/rpcs3/Emu/RSX/color_utils.h b/rpcs3/Emu/RSX/Utils/color_utils.hpp similarity index 96% rename from rpcs3/Emu/RSX/color_utils.h rename to rpcs3/Emu/RSX/Utils/color_utils.hpp index 9a37171780..d18d1a2763 100644 --- a/rpcs3/Emu/RSX/color_utils.h +++ b/rpcs3/Emu/RSX/Utils/color_utils.hpp @@ -2,7 +2,7 @@ #include #include -#include "gcm_enums.h" +#include "../gcm_enums.h" #include "Utilities/StrFmt.h" namespace rsx diff --git a/rpcs3/Emu/RSX/Utils/image_utils.hpp b/rpcs3/Emu/RSX/Utils/image_utils.hpp new file mode 100644 index 0000000000..2a6f89118e --- /dev/null +++ b/rpcs3/Emu/RSX/Utils/image_utils.hpp @@ -0,0 +1,188 @@ +#pragma once + +#include +#include "algorithm.hpp" + +extern "C" +{ +#include +} + +namespace rsx +{ + template + void pad_texture(const void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 /*output_height*/) + { + const T *src = static_cast(input_pixels); + T *dst = static_cast(output_pixels); + + for (u16 h = 0; h < input_height; ++h) + { + const u32 padded_pos = h * output_width; + const u32 pos = h * input_width; + for (u16 w = 0; w < input_width; ++w) + { + dst[padded_pos + w] = src[pos + w]; + } + } + } + + // Returns interleaved bits of X|Y|Z used as Z-order curve indices + static inline u32 calculate_z_index(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth) + { + AUDIT(x < (1u << log2_width) && y < (1u << log2_height) && z < (1u << log2_depth)); + + // offset = X' | Y' | Z' which are x,y,z bits interleaved + u32 offset = 0; + u32 shift_count = 0; + do + { + if (log2_width) + { + offset |= (x & 0x1) << shift_count++; + x >>= 1; + log2_width--; + } + + if (log2_height) + { + offset |= (y & 0x1) << shift_count++; + y >>= 1; + log2_height--; + } + + if (log2_depth) + { + offset |= (z & 0x1) << shift_count++; + z >>= 1; + log2_depth--; + } + } + while (x | y | z); + + return offset; + } + + /* Note: What the ps3 calls swizzling in this case is actually z-ordering / morton ordering of pixels + * - Input can be swizzled or linear, bool flag handles conversion to and from + * - It will handle any width and height that are a power of 2, square or non square + * Restriction: It has mixed results if the height or width is not a power of 2 + * Restriction: Only works with 2D surfaces + */ + template + void convert_linear_swizzle(const void* input_pixels, void* output_pixels, u16 width, u16 height, u32 pitch) + { + const u32 log2width = ceil_log2(width); + const u32 log2height = ceil_log2(height); + + // Max mask possible for square texture + u32 x_mask = 0x55555555; + u32 y_mask = 0xAAAAAAAA; + + // We have to limit the masks to the lower of the two dimensions to allow for non-square textures + u32 limit_mask = (log2width < log2height) ? log2width : log2height; + // double the limit mask to account for bits in both x and y + limit_mask = 1 << (limit_mask << 1); + + //x_mask, bits above limit are 1's for x-carry + x_mask = (x_mask | ~(limit_mask - 1)); + //y_mask. bits above limit are 0'd, as we use a different method for y-carry over + y_mask = (y_mask & (limit_mask - 1)); + + u32 offs_y = 0; + u32 offs_x = 0; + u32 offs_x0 = 0; //total y-carry offset for x + const u32 y_incr = limit_mask; + + // NOTE: The swizzled area is always a POT region and we must scan all of it to fill in the linear. + // It is assumed that there is no padding on the linear side for simplicity - backend upload/download will crop as needed. + // Remember, in cases of swizzling (and also tiled addressing) it is possible for tiled pixels to fall outside of their linear memory region. + const u32 pitch_in_blocks = pitch / sizeof(T); + u32 row_offset = 0; + + if constexpr (!input_is_swizzled) + { + for (int y = 0; y < height; ++y, row_offset += pitch_in_blocks) + { + auto src = static_cast(input_pixels) + row_offset; + auto dst = static_cast(output_pixels) + offs_y; + offs_x = offs_x0; + + for (int x = 0; x < width; ++x) + { + dst[offs_x] = src[x]; + offs_x = (offs_x - x_mask) & x_mask; + } + + offs_y = (offs_y - y_mask) & y_mask; + + if (offs_y == 0) + { + offs_x0 += y_incr; + } + } + } + else + { + for (int y = 0; y < height; ++y, row_offset += pitch_in_blocks) + { + auto src = static_cast(input_pixels) + offs_y; + auto dst = static_cast(output_pixels) + row_offset; + offs_x = offs_x0; + + for (int x = 0; x < width; ++x) + { + dst[x] = src[offs_x]; + offs_x = (offs_x - x_mask) & x_mask; + } + + offs_y = (offs_y - y_mask) & y_mask; + + if (offs_y == 0) + { + offs_x0 += y_incr; + } + } + } + } + + /** + * Write swizzled data to linear memory with support for 3 dimensions + * Z ordering is done in all 3 planes independently with a unit being a 2x2 block per-plane + * A unit in 3d textures is a group of 2x2x2 texels advancing towards depth in units of 2x2x1 blocks + * i.e 32 texels per "unit" + */ + template + void convert_linear_swizzle_3d(const void* input_pixels, void* output_pixels, u16 width, u16 height, u16 depth) + { + if (depth == 1) + { + convert_linear_swizzle(input_pixels, output_pixels, width, height, width * sizeof(T)); + return; + } + + auto src = static_cast(input_pixels); + auto dst = static_cast(output_pixels); + + const u32 log2_w = ceil_log2(width); + const u32 log2_h = ceil_log2(height); + const u32 log2_d = ceil_log2(depth); + + for (u32 z = 0; z < depth; ++z) + { + for (u32 y = 0; y < height; ++y) + { + for (u32 x = 0; x < width; ++x) + { + *dst++ = src[calculate_z_index(x, y, z, log2_w, log2_h, log2_d)]; + } + } + } + } + + void convert_scale_image(u8 *dst, AVPixelFormat dst_format, int dst_width, int dst_height, int dst_pitch, + const u8 *src, AVPixelFormat src_format, int src_width, int src_height, int src_pitch, int src_slice_h, bool bilinear); + + void clip_image(u8 *dst, const u8 *src, int clip_x, int clip_y, int clip_w, int clip_h, int bpp, int src_pitch, int dst_pitch); + void clip_image_may_overlap(u8 *dst, const u8 *src, int clip_x, int clip_y, int clip_w, int clip_h, int bpp, int src_pitch, int dst_pitch, u8* buffer); +} diff --git a/rpcs3/Emu/RSX/rsx_utils.cpp b/rpcs3/Emu/RSX/Utils/rsx_utils.cpp similarity index 99% rename from rpcs3/Emu/RSX/rsx_utils.cpp rename to rpcs3/Emu/RSX/Utils/rsx_utils.cpp index 9ce4565139..c2f65b9d36 100644 --- a/rpcs3/Emu/RSX/rsx_utils.cpp +++ b/rpcs3/Emu/RSX/Utils/rsx_utils.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "rsx_utils.h" -#include "rsx_methods.h" +#include "Emu/RSX/rsx_methods.h" #include "Emu/Cell/Modules/cellVideoOut.h" #ifdef _MSC_VER diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/Utils/rsx_utils.h similarity index 68% rename from rpcs3/Emu/RSX/rsx_utils.h rename to rpcs3/Emu/RSX/Utils/rsx_utils.h index 79aef602c6..1c21007a70 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/Utils/rsx_utils.h @@ -1,14 +1,9 @@ #pragma once -#include "../system_config.h" +#include "../../system_config.h" #include "Utilities/address_range.h" #include "Utilities/geometry.h" -#include "gcm_enums.h" - -extern "C" -{ -#include -} +#include "../gcm_enums.h" #define RSX_SURFACE_DIMENSION_IGNORED 1 @@ -228,45 +223,6 @@ namespace rsx } }; - template - void pad_texture(const void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 /*output_height*/) - { - const T *src = static_cast(input_pixels); - T *dst = static_cast(output_pixels); - - for (u16 h = 0; h < input_height; ++h) - { - const u32 padded_pos = h * output_width; - const u32 pos = h * input_width; - for (u16 w = 0; w < input_width; ++w) - { - dst[padded_pos + w] = src[pos + w]; - } - } - } - - static constexpr u32 floor_log2(u32 value) - { - return value <= 1 ? 0 : std::countl_zero(value) ^ 31; - } - - static constexpr u32 ceil_log2(u32 value) - { - return floor_log2(value) + u32{!!(value & (value - 1))}; - } - - static constexpr u32 next_pow2(u32 x) - { - if (x <= 2) return x; - - return static_cast((1ULL << 32) >> std::countl_zero(x - 1)); - } - - static inline bool fcmp(float a, float b, float epsilon = 0.000001f) - { - return fabsf(a - b) < epsilon; - } - // Returns an ever-increasing tag value static inline u64 get_shared_tag() { @@ -282,190 +238,6 @@ namespace rsx CELL_GCM_LOCATION_MAIN; } - // General purpose alignment without power-of-2 constraint - template - static inline T align2(T value, U alignment) - { - return ((value + alignment - 1) / alignment) * alignment; - } - - // General purpose downward alignment without power-of-2 constraint - template - static inline T align_down2(T value, U alignment) - { - return (value / alignment) * alignment; - } - - // Copy memory in inverse direction from source - // Used to scale negatively x axis while transfering image data - template - static void memcpy_r(void* dst, void* src, usz size) - { - for (u32 i = 0; i < size; i++) - { - *(static_cast(dst) + i) = *(static_cast(src) - i); - } - } - - // Returns interleaved bits of X|Y|Z used as Z-order curve indices - static inline u32 calculate_z_index(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth) - { - AUDIT(x < (1u << log2_width) && y < (1u << log2_height) && z < (1u << log2_depth)); - - // offset = X' | Y' | Z' which are x,y,z bits interleaved - u32 offset = 0; - u32 shift_count = 0; - do - { - if (log2_width) - { - offset |= (x & 0x1) << shift_count++; - x >>= 1; - log2_width--; - } - - if (log2_height) - { - offset |= (y & 0x1) << shift_count++; - y >>= 1; - log2_height--; - } - - if (log2_depth) - { - offset |= (z & 0x1) << shift_count++; - z >>= 1; - log2_depth--; - } - } - while (x | y | z); - - return offset; - } - - /* Note: What the ps3 calls swizzling in this case is actually z-ordering / morton ordering of pixels - * - Input can be swizzled or linear, bool flag handles conversion to and from - * - It will handle any width and height that are a power of 2, square or non square - * Restriction: It has mixed results if the height or width is not a power of 2 - * Restriction: Only works with 2D surfaces - */ - template - void convert_linear_swizzle(const void* input_pixels, void* output_pixels, u16 width, u16 height, u32 pitch) - { - const u32 log2width = ceil_log2(width); - const u32 log2height = ceil_log2(height); - - // Max mask possible for square texture - u32 x_mask = 0x55555555; - u32 y_mask = 0xAAAAAAAA; - - // We have to limit the masks to the lower of the two dimensions to allow for non-square textures - u32 limit_mask = (log2width < log2height) ? log2width : log2height; - // double the limit mask to account for bits in both x and y - limit_mask = 1 << (limit_mask << 1); - - //x_mask, bits above limit are 1's for x-carry - x_mask = (x_mask | ~(limit_mask - 1)); - //y_mask. bits above limit are 0'd, as we use a different method for y-carry over - y_mask = (y_mask & (limit_mask - 1)); - - u32 offs_y = 0; - u32 offs_x = 0; - u32 offs_x0 = 0; //total y-carry offset for x - const u32 y_incr = limit_mask; - - // NOTE: The swizzled area is always a POT region and we must scan all of it to fill in the linear. - // It is assumed that there is no padding on the linear side for simplicity - backend upload/download will crop as needed. - // Remember, in cases of swizzling (and also tiled addressing) it is possible for tiled pixels to fall outside of their linear memory region. - const u32 pitch_in_blocks = pitch / sizeof(T); - u32 row_offset = 0; - - if constexpr (!input_is_swizzled) - { - for (int y = 0; y < height; ++y, row_offset += pitch_in_blocks) - { - auto src = static_cast(input_pixels) + row_offset; - auto dst = static_cast(output_pixels) + offs_y; - offs_x = offs_x0; - - for (int x = 0; x < width; ++x) - { - dst[offs_x] = src[x]; - offs_x = (offs_x - x_mask) & x_mask; - } - - offs_y = (offs_y - y_mask) & y_mask; - - if (offs_y == 0) - { - offs_x0 += y_incr; - } - } - } - else - { - for (int y = 0; y < height; ++y, row_offset += pitch_in_blocks) - { - auto src = static_cast(input_pixels) + offs_y; - auto dst = static_cast(output_pixels) + row_offset; - offs_x = offs_x0; - - for (int x = 0; x < width; ++x) - { - dst[x] = src[offs_x]; - offs_x = (offs_x - x_mask) & x_mask; - } - - offs_y = (offs_y - y_mask) & y_mask; - - if (offs_y == 0) - { - offs_x0 += y_incr; - } - } - } - } - - /** - * Write swizzled data to linear memory with support for 3 dimensions - * Z ordering is done in all 3 planes independently with a unit being a 2x2 block per-plane - * A unit in 3d textures is a group of 2x2x2 texels advancing towards depth in units of 2x2x1 blocks - * i.e 32 texels per "unit" - */ - template - void convert_linear_swizzle_3d(const void* input_pixels, void* output_pixels, u16 width, u16 height, u16 depth) - { - if (depth == 1) - { - convert_linear_swizzle(input_pixels, output_pixels, width, height, width * sizeof(T)); - return; - } - - auto src = static_cast(input_pixels); - auto dst = static_cast(output_pixels); - - const u32 log2_w = ceil_log2(width); - const u32 log2_h = ceil_log2(height); - const u32 log2_d = ceil_log2(depth); - - for (u32 z = 0; z < depth; ++z) - { - for (u32 y = 0; y < height; ++y) - { - for (u32 x = 0; x < width; ++x) - { - *dst++ = src[calculate_z_index(x, y, z, log2_w, log2_h, log2_d)]; - } - } - } - } - - void convert_scale_image(u8 *dst, AVPixelFormat dst_format, int dst_width, int dst_height, int dst_pitch, - const u8 *src, AVPixelFormat src_format, int src_width, int src_height, int src_pitch, int src_slice_h, bool bilinear); - - void clip_image(u8 *dst, const u8 *src, int clip_x, int clip_y, int clip_w, int clip_h, int bpp, int src_pitch, int dst_pitch); - void clip_image_may_overlap(u8 *dst, const u8 *src, int clip_x, int clip_y, int clip_w, int clip_h, int bpp, int src_pitch, int dst_pitch, u8* buffer); - std::array get_constant_blend_colors(); /** diff --git a/rpcs3/Emu/RSX/VK/VKCompute.h b/rpcs3/Emu/RSX/VK/VKCompute.h index 81f8d6a165..9b69688f2e 100644 --- a/rpcs3/Emu/RSX/VK/VKCompute.h +++ b/rpcs3/Emu/RSX/VK/VKCompute.h @@ -1,9 +1,10 @@ #pragma once -#include "Emu/RSX/VK/VKProgramPipeline.h" +#include "VKProgramPipeline.h" #include "vkutils/descriptors.h" #include "vkutils/buffer_object.h" #include "Emu/IdManager.h" +#include "Emu/RSX/Utils/algorithm.hpp" #include "Utilities/StrUtil.h" #include "util/asm.hpp" diff --git a/rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp b/rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp index 0b80a5d4e6..f817fe363f 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp +++ b/rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp @@ -6,7 +6,7 @@ #include "VKResourceManager.h" #include "Emu/RSX/Common/simple_array.hpp" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/rsx_utils.h" #include "Emu/RSX/rsx_cache.h" #include "Utilities/mutex.h" #include "util/asm.hpp" diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index ac96e2ac4e..6cbb33c39e 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -6,7 +6,7 @@ #include "VulkanAPI.h" #include "Utilities/geometry.h" #include "Emu/RSX/Common/TextureUtils.h" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/rsx_utils.h" #define OCCLUSION_MAX_POOL_SIZE DESCRIPTOR_MAX_DRAW_CALLS diff --git a/rpcs3/Emu/RSX/VK/VKTexture.cpp b/rpcs3/Emu/RSX/VK/VKTexture.cpp index 30cff2a067..b969d6403f 100644 --- a/rpcs3/Emu/RSX/VK/VKTexture.cpp +++ b/rpcs3/Emu/RSX/VK/VKTexture.cpp @@ -11,7 +11,7 @@ #include "VKGSRender.h" #include "../GCM.h" -#include "../rsx_utils.h" +#include "../Utils/rsx_utils.h" #include "Utilities/deferred_op.hpp" #include "util/asm.hpp" diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index c000092987..597de750c4 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -8,6 +8,7 @@ #include "../Common/texture_cache.h" #include "../Common/tiled_dma_copy.hpp" +#include "../Utils/image_utils.hpp" #include #include diff --git a/rpcs3/Emu/RSX/VK/vkutils/image_helpers.cpp b/rpcs3/Emu/RSX/VK/vkutils/image_helpers.cpp index 2e97e5ad22..5b96c13e40 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image_helpers.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/image_helpers.cpp @@ -2,7 +2,7 @@ #include "image_helpers.h" #include "image.h" #include "../VKRenderPass.h" -#include "../../color_utils.h" +#include "../../Utils/color_utils.hpp" namespace vk { diff --git a/rpcs3/Emu/RSX/VK/vkutils/memory.cpp b/rpcs3/Emu/RSX/VK/vkutils/memory.cpp index fcb1d448d4..b7f018a799 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/memory.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/memory.cpp @@ -1,15 +1,7 @@ #include "device.h" #include "memory.h" -namespace -{ - // Copied from rsx_utils.h. Move to a more convenient location - template - static inline T align2(T value, U alignment) - { - return ((value + alignment - 1) / alignment) * alignment; - } -} +#include "Emu/RSX/Utils/algorithm.hpp" namespace vk { @@ -236,7 +228,7 @@ namespace vk for (const auto& memory_type_index : *request.memory_type) { mem_req.memoryTypeBits = 1u << memory_type_index; - mem_req.size = ::align2(request.size, request.alignment); + mem_req.size = rsx::align2(request.size, request.alignment); mem_req.alignment = request.alignment; create_info.memoryTypeBits = 1u << memory_type_index; create_info.flags = m_allocation_flags; diff --git a/rpcs3/Emu/RSX/VK/vkutils/memory.h b/rpcs3/Emu/RSX/VK/vkutils/memory.h index 5c4d05ecdf..834c7778f2 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/memory.h +++ b/rpcs3/Emu/RSX/VK/vkutils/memory.h @@ -1,9 +1,9 @@ #pragma once -#include "../VulkanAPI.h" -#include "../../rsx_utils.h" #include "shared.h" +#include "Emu/RSX/Utils/rsx_utils.h" + #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnullability-completeness" diff --git a/rpcs3/Emu/RSX/VK/vkutils/query_pool.hpp b/rpcs3/Emu/RSX/VK/vkutils/query_pool.hpp index 0e480c2d0a..dc1763f84b 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/query_pool.hpp +++ b/rpcs3/Emu/RSX/VK/vkutils/query_pool.hpp @@ -1,8 +1,7 @@ #pragma once -#include "../VulkanAPI.h" -#include "../../rsx_utils.h" #include "shared.h" +#include "../../Utils/rsx_utils.h" namespace vk { diff --git a/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp b/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp index 53066e2f4a..37bd9867e4 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/sampler.cpp @@ -1,7 +1,7 @@ #include "memory.h" #include "sampler.h" -#include "../../color_utils.h" -#include "../../rsx_utils.h" +#include "../../Utils/color_utils.hpp" +#include "../../Utils/algorithm.hpp" namespace vk { diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h index 3571ec194f..341a33d846 100644 --- a/rpcs3/Emu/RSX/rsx_decode.h +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -6,7 +6,7 @@ #include #include #include "gcm_enums.h" -#include "rsx_utils.h" +#include "Utils/rsx_utils.h" namespace rsx { diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 9dc04b6758..d0d2b9ecc6 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -522,7 +522,7 @@ - + NotUsing @@ -682,7 +682,6 @@ - @@ -1073,7 +1072,10 @@ - + + + + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 1afdf03197..8b4bc00d21 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1333,7 +1333,7 @@ Emu\GPU\RSX\Utils - + Emu\GPU\RSX\Utils @@ -2800,9 +2800,6 @@ Emu\GPU\RSX\Utils - - Emu\GPU\RSX\Utils - Emu\GPU\RSX\Host Mini-Driver @@ -2830,7 +2827,16 @@ Emu\GPU\RSX\Utils - + + Emu\GPU\RSX\Utils + + + Emu\GPU\RSX\Utils + + + Emu\GPU\RSX\Utils + + Emu\GPU\RSX\Utils diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index d4afc08b37..9e88d914f9 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -16,7 +16,8 @@ #include "Emu/Cell/Modules/cellAudio.h" #include "Emu/Cell/lv2/sys_rsxaudio.h" #include "Emu/RSX/RSXThread.h" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/image_utils.hpp" +#include "Emu/RSX/Utils/rsx_utils.h" #include "Emu/RSX/Overlays/overlay_message.h" #include "Emu/Io/interception.h" #include "Emu/Io/recording_config.h" diff --git a/rpcs3/rpcs3qt/memory_viewer_panel.cpp b/rpcs3/rpcs3qt/memory_viewer_panel.cpp index 7026a334ed..e3ad9f9688 100644 --- a/rpcs3/rpcs3qt/memory_viewer_panel.cpp +++ b/rpcs3/rpcs3qt/memory_viewer_panel.cpp @@ -7,7 +7,7 @@ #include "Emu/Cell/SPUThread.h" #include "Emu/CPU/CPUDisAsm.h" #include "Emu/RSX/RSXThread.h" -#include "Emu/RSX/rsx_utils.h" +#include "Emu/RSX/Utils/rsx_utils.h" #include "Emu/IdManager.h" #include "Emu/System.h" #include