From e6b81a65c0c37042096fb128aa029c3eb6d4ffc6 Mon Sep 17 00:00:00 2001 From: Fire Cube Date: Sun, 20 Apr 2025 13:50:28 +0200 Subject: [PATCH] add macro 16bpp implementation --- src/video_core/host_shaders/CMakeLists.txt | 1 + .../host_shaders/detilers/macro_16bpp.comp | 73 +++++++++++++++++++ src/video_core/texture_cache/tile_manager.cpp | 15 ++-- src/video_core/texture_cache/tile_manager.h | 1 + 4 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 src/video_core/host_shaders/detilers/macro_16bpp.comp diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 3001bf773..055fa0ff2 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt @@ -3,6 +3,7 @@ set(SHADER_FILES detilers/display_micro_64bpp.comp + detilers/macro_16bpp.comp detilers/macro_32bpp.comp detilers/macro_64bpp.comp detilers/macro_8bpp.comp diff --git a/src/video_core/host_shaders/detilers/macro_16bpp.comp b/src/video_core/host_shaders/detilers/macro_16bpp.comp new file mode 100644 index 000000000..b3ec60f80 --- /dev/null +++ b/src/video_core/host_shaders/detilers/macro_16bpp.comp @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#version 450 + +layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; + +layout(std430, binding = 0) buffer input_buf { uint in_data[]; }; +layout(std430, binding = 1) buffer output_buf { uint out_data[]; }; + +layout(push_constant) uniform image_info { + uint num_levels; + uint pitch; + uint height; + uint c0; + uint c1; +} info; + +#define MICRO_TILE_DIM 8u +#define BPP 16u +#define MICRO_TILE_SZ 512u +shared uint scratch[32]; + +uint calc_micro_idx(uint col, uint row, uint slice2) +{ + uint idx = 0u; + idx |= (col & 1u) << 0u; + idx |= (row & 1u) << 1u; + idx |= (col & 2u) << 1u; + idx |= (row & 2u) << 2u; + idx |= (col & 4u) << 2u; + idx |= (row & 4u) << 3u; + idx |= slice2 << 6u; + return idx; +} + +void main() +{ + uint lane = gl_LocalInvocationID.x; + uint slot = lane >> 1u; + uint halfIdx = lane & 1u; + + if (halfIdx == 0u) scratch[slot] = 0u; + barrier(); + + uint linear = gl_GlobalInvocationID.x; + uint x = linear % info.pitch; + uint y = (linear / info.pitch) % info.height; + uint z = linear / (info.pitch * info.height); + + uint col = x & 7u; + uint row = y & 7u; + uint idx = calc_micro_idx(col, row, z & 3u); + + uint slice_offs = (z >> 2u) * info.c1 * MICRO_TILE_SZ; + uint tile_row = y / MICRO_TILE_DIM; + uint tile_col = x / MICRO_TILE_DIM; + uint tile_offs = ((tile_row * info.c0) + tile_col) * MICRO_TILE_SZ; + uint offs = slice_offs + tile_offs + idx * 2u; // 2 B/Texel + + uint word = in_data[offs >> 2u]; + int shift = int((offs & 2u) * 8u); // 0 oder 16 + uint tex16 = bitfieldExtract(word, shift, 16); + + + uint mask = tex16 << (halfIdx * 16u); + scratch[slot] |= mask; + + barrier(); + + if (halfIdx == 0u) + out_data[linear >> 1u] = scratch[slot]; +} diff --git a/src/video_core/texture_cache/tile_manager.cpp b/src/video_core/texture_cache/tile_manager.cpp index d7fc54338..f4b057a47 100644 --- a/src/video_core/texture_cache/tile_manager.cpp +++ b/src/video_core/texture_cache/tile_manager.cpp @@ -9,6 +9,7 @@ #include "video_core/texture_cache/tile_manager.h" #include "video_core/host_shaders/detilers/display_micro_64bpp_comp.h" +#include "video_core/host_shaders/detilers/macro_16bpp_comp.h" #include "video_core/host_shaders/detilers/macro_32bpp_comp.h" #include "video_core/host_shaders/detilers/macro_64bpp_comp.h" #include "video_core/host_shaders/detilers/macro_8bpp_comp.h" @@ -46,6 +47,10 @@ const DetilerContext* TileManager::GetDetiler(const ImageInfo& info) const { switch (bpp) { case 8: return &detilers[DetilerType::Macro8]; + case 16: + LOG_INFO(Render_Vulkan, "Using 16bpp detiler for volume texture: {} ({})", + vk::to_string(info.pixel_format), NameOf(info.tiling_mode)); + return &detilers[DetilerType::Macro16]; case 32: return &detilers[DetilerType::Macro32]; case 64: @@ -77,11 +82,11 @@ struct DetilerParams { TileManager::TileManager(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler) : instance{instance}, scheduler{scheduler} { static const std::array detiler_shaders{ - HostShaders::MICRO_8BPP_COMP, HostShaders::MICRO_16BPP_COMP, - HostShaders::MICRO_32BPP_COMP, HostShaders::MICRO_64BPP_COMP, - HostShaders::MICRO_128BPP_COMP, HostShaders::MACRO_8BPP_COMP, - HostShaders::MACRO_32BPP_COMP, HostShaders::MACRO_64BPP_COMP, - HostShaders::DISPLAY_MICRO_64BPP_COMP, + HostShaders::MICRO_8BPP_COMP, HostShaders::MICRO_16BPP_COMP, + HostShaders::MICRO_32BPP_COMP, HostShaders::MICRO_64BPP_COMP, + HostShaders::MICRO_128BPP_COMP, HostShaders::MACRO_8BPP_COMP, + HostShaders::MACRO_16BPP_COMP, HostShaders::MACRO_32BPP_COMP, + HostShaders::MACRO_64BPP_COMP, HostShaders::DISPLAY_MICRO_64BPP_COMP, }; boost::container::static_vector bindings{ diff --git a/src/video_core/texture_cache/tile_manager.h b/src/video_core/texture_cache/tile_manager.h index adda16b3d..bd2962114 100644 --- a/src/video_core/texture_cache/tile_manager.h +++ b/src/video_core/texture_cache/tile_manager.h @@ -19,6 +19,7 @@ enum DetilerType : u32 { Micro128, Macro8, + Macro16, Macro32, Macro64,